1*4efd5405Schristos /* $NetBSD: umount.c,v 1.53 2020/04/23 04:21:13 christos Exp $ */
20114e805Scgd
361f28255Scgd /*-
4bab81812Smycroft * Copyright (c) 1980, 1989, 1993
5bab81812Smycroft * The Regents of the University of California. All rights reserved.
661f28255Scgd *
761f28255Scgd * Redistribution and use in source and binary forms, with or without
861f28255Scgd * modification, are permitted provided that the following conditions
961f28255Scgd * are met:
1061f28255Scgd * 1. Redistributions of source code must retain the above copyright
1161f28255Scgd * notice, this list of conditions and the following disclaimer.
1261f28255Scgd * 2. Redistributions in binary form must reproduce the above copyright
1361f28255Scgd * notice, this list of conditions and the following disclaimer in the
1461f28255Scgd * documentation and/or other materials provided with the distribution.
15276d62f6Sagc * 3. Neither the name of the University nor the names of its contributors
1661f28255Scgd * may be used to endorse or promote products derived from this software
1761f28255Scgd * without specific prior written permission.
1861f28255Scgd *
1961f28255Scgd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2061f28255Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2161f28255Scgd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2261f28255Scgd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2361f28255Scgd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2461f28255Scgd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2561f28255Scgd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2661f28255Scgd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2761f28255Scgd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2861f28255Scgd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2961f28255Scgd * SUCH DAMAGE.
3061f28255Scgd */
3161f28255Scgd
32788a7903Slukem #include <sys/cdefs.h>
3361f28255Scgd #ifndef lint
346543a91fSlukem __COPYRIGHT("@(#) Copyright (c) 1980, 1989, 1993\
356543a91fSlukem The Regents of the University of California. All rights reserved.");
3661f28255Scgd #endif /* not lint */
3761f28255Scgd
3861f28255Scgd #ifndef lint
390114e805Scgd #if 0
4056638e9dSlukem static char sccsid[] = "@(#)umount.c 8.8 (Berkeley) 5/8/95";
410114e805Scgd #else
42*4efd5405Schristos __RCSID("$NetBSD: umount.c,v 1.53 2020/04/23 04:21:13 christos Exp $");
430114e805Scgd #endif
4461f28255Scgd #endif /* not lint */
4561f28255Scgd
4661f28255Scgd #include <sys/param.h>
4761f28255Scgd #include <sys/stat.h>
4861f28255Scgd #include <sys/mount.h>
4961f28255Scgd #include <sys/time.h>
50ba0b3992Schristos #ifndef SMALL
5161f28255Scgd #include <sys/socket.h>
52bab81812Smycroft
5361f28255Scgd #include <netdb.h>
5461f28255Scgd #include <rpc/rpc.h>
5561f28255Scgd #include <rpc/pmap_clnt.h>
5661f28255Scgd #include <rpc/pmap_prot.h>
5761f28255Scgd #include <nfs/rpcv2.h>
58958c0aacSchristos #include <nfs/nfsmount.h>
59ba0b3992Schristos #endif /* !SMALL */
6061f28255Scgd
615334ad51Scgd #include <err.h>
624cc121caSdholland #include <errno.h>
6361f28255Scgd #include <fstab.h>
6461f28255Scgd #include <stdio.h>
655334ad51Scgd #include <stdlib.h>
66bab81812Smycroft #include <string.h>
675334ad51Scgd #include <unistd.h>
68*4efd5405Schristos #include <util.h>
6961f28255Scgd
7098bd013cSpk typedef enum { MNTANY, MNTON, MNTFROM } mntwhat;
7161f28255Scgd
72ba0b3992Schristos #ifndef SMALL
7399fed726Spooka #include "mountprog.h"
7461f28255Scgd
75ba0b3992Schristos static int fake, verbose;
76ba0b3992Schristos static char *nfshost;
77ba0b3992Schristos static struct addrinfo *nfshost_ai = NULL;
78ba0b3992Schristos
79ba0b3992Schristos static int namematch(const struct addrinfo *);
80ba0b3992Schristos static int sacmp(const struct sockaddr *, const struct sockaddr *);
81ba0b3992Schristos static int xdr_dir(XDR *, char *);
82da960e08Schristos static const char *getmntproto(const char *);
83ba0b3992Schristos #endif /* !SMALL */
84ba0b3992Schristos
85a3b206f6Schs static int fflag;
86ba0b3992Schristos static char *getmntname(const char *, mntwhat, char **);
87a3b206f6Schs static int umountfs(const char *, const char **, int);
888b0f9554Sperry static void usage(void) __dead;
89ba0b3992Schristos
905334ad51Scgd int
main(int argc,char * argv[])91ff49552bSdsl main(int argc, char *argv[])
9261f28255Scgd {
93a3b206f6Schs int ch, errs, all = 0, raw = 0;
94*4efd5405Schristos char mntfromname[MAXPATHLEN];
95ba0b3992Schristos #ifndef SMALL
96ba0b3992Schristos int mnts;
976bd1d6d4Schristos struct statvfs *mntbuf;
98d6548209Sfvdl struct addrinfo hints;
99ba0b3992Schristos #endif /* SMALL */
100ba0b3992Schristos const char **typelist = NULL;
10161f28255Scgd
102ba0b3992Schristos #ifdef SMALL
103a432762dSerh #define OPTS "fR"
104ba0b3992Schristos #else
105ba0b3992Schristos #define OPTS "AaFfh:Rt:v"
106ba0b3992Schristos #endif
107ba0b3992Schristos while ((ch = getopt(argc, argv, OPTS)) != -1)
108bab81812Smycroft switch (ch) {
109ba0b3992Schristos case 'f':
110ba0b3992Schristos fflag = MNT_FORCE;
111ba0b3992Schristos break;
112ba0b3992Schristos case 'R':
113ba0b3992Schristos raw = 1;
114ba0b3992Schristos break;
115ba0b3992Schristos #ifndef SMALL
11656638e9dSlukem case 'A':
117bab81812Smycroft case 'a':
118bab81812Smycroft all = 1;
119bab81812Smycroft break;
120bab81812Smycroft case 'F':
121bab81812Smycroft fake = 1;
12261f28255Scgd break;
12356638e9dSlukem case 'h': /* -h implies -A. */
12409218270Schs all = 1;
125bab81812Smycroft nfshost = optarg;
12661f28255Scgd break;
12761f28255Scgd case 't':
12863292a1aSmycroft if (typelist != NULL)
12963292a1aSmycroft errx(1, "only one -t option may be specified.");
13056638e9dSlukem typelist = makevfslist(optarg);
13161f28255Scgd break;
132bab81812Smycroft case 'v':
13363292a1aSmycroft verbose = 1;
13461f28255Scgd break;
135ba0b3992Schristos #endif /* !SMALL */
13661f28255Scgd default:
13761f28255Scgd usage();
13861f28255Scgd /* NOTREACHED */
13961f28255Scgd }
14061f28255Scgd argc -= optind;
14161f28255Scgd argv += optind;
14261f28255Scgd
1439fc45bafSfair if ((argc == 0 && !all) || (argc != 0 && all) || (all && raw))
14461f28255Scgd usage();
145bab81812Smycroft
146ba0b3992Schristos #ifndef SMALL
147bab81812Smycroft /* -h implies "-t nfs" if no -t flag. */
148bab81812Smycroft if ((nfshost != NULL) && (typelist == NULL))
14956638e9dSlukem typelist = makevfslist("nfs");
150bab81812Smycroft
151d6548209Sfvdl if (nfshost != NULL) {
152d6548209Sfvdl memset(&hints, 0, sizeof hints);
153ece47fa3Sdholland if (getaddrinfo(nfshost, NULL, &hints, &nfshost_ai) != 0) {
154ece47fa3Sdholland nfshost_ai = NULL;
155ece47fa3Sdholland }
156d6548209Sfvdl }
157d6548209Sfvdl
15856638e9dSlukem errs = 0;
15909218270Schs if (all) {
160ba0b3992Schristos if ((mnts = getmntinfo(&mntbuf, ST_NOWAIT)) == 0) {
16156638e9dSlukem warn("getmntinfo");
162bab81812Smycroft errs = 1;
16356638e9dSlukem }
16456638e9dSlukem for (errs = 0, mnts--; mnts > 0; mnts--) {
16556638e9dSlukem if (checkvfsname(mntbuf[mnts].f_fstypename, typelist))
16656638e9dSlukem continue;
167a3b206f6Schs if (umountfs(mntbuf[mnts].f_mntonname, typelist,
168a432762dSerh 1) != 0)
16956638e9dSlukem errs = 1;
17056638e9dSlukem }
171ba0b3992Schristos } else
172ba0b3992Schristos #endif /* !SMALL */
173*4efd5405Schristos for (errs = 0; *argv != NULL; ++argv) {
174*4efd5405Schristos if (getfsspecname(mntfromname, sizeof(mntfromname),
175*4efd5405Schristos *argv) == NULL)
176*4efd5405Schristos err(EXIT_FAILURE, "%s", mntfromname);
177*4efd5405Schristos if (umountfs(mntfromname, typelist, raw) != 0)
17856638e9dSlukem errs = 1;
179*4efd5405Schristos }
180ba0b3992Schristos return errs;
18161f28255Scgd }
18261f28255Scgd
183ba0b3992Schristos static int
umountfs(const char * name,const char ** typelist,int raw)184a3b206f6Schs umountfs(const char *name, const char **typelist, int raw)
18561f28255Scgd {
186ba0b3992Schristos #ifndef SMALL
18761f28255Scgd enum clnt_stat clnt_stat;
188d6548209Sfvdl struct timeval try;
189bab81812Smycroft CLIENT *clp;
190ba0b3992Schristos char *hostp = NULL;
191ba0b3992Schristos struct addrinfo *ai = NULL, hints;
192b8a7bdb6Schristos const char *proto = NULL;
193ba0b3992Schristos #endif /* !SMALL */
1948cc28b4bSdsl const char *mntpt;
1954cc121caSdholland char *type, rname[MAXPATHLEN], umountprog[MAXPATHLEN];
196ba0b3992Schristos mntwhat what;
197ba0b3992Schristos struct stat sb;
1989fc45bafSfair
1999fc45bafSfair if (raw) {
2009fc45bafSfair mntpt = name;
2019fc45bafSfair } else {
2029fc45bafSfair
20398bd013cSpk what = MNTANY;
204b4712500Sdsl if (realpath(name, rname) != NULL) {
205b4712500Sdsl name = rname;
206bab81812Smycroft
20798bd013cSpk if (stat(name, &sb) == 0) {
20898bd013cSpk if (S_ISBLK(sb.st_mode))
20998bd013cSpk what = MNTON;
21098bd013cSpk else if (S_ISDIR(sb.st_mode))
21198bd013cSpk what = MNTFROM;
21298bd013cSpk }
213b4712500Sdsl }
214ba0b3992Schristos #ifdef SMALL
215ba0b3992Schristos else {
21675cbf5e1Sdholland warn("%s", name);
217ba0b3992Schristos return 1;
218ba0b3992Schristos }
219ba0b3992Schristos #endif /* SMALL */
220b4712500Sdsl mntpt = name;
22198bd013cSpk
22298bd013cSpk switch (what) {
22398bd013cSpk case MNTON:
22456638e9dSlukem if ((mntpt = getmntname(name, MNTON, &type)) == NULL) {
225bab81812Smycroft warnx("%s: not currently mounted", name);
226bab81812Smycroft return (1);
227bab81812Smycroft }
22898bd013cSpk break;
22998bd013cSpk case MNTFROM:
23056638e9dSlukem if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) {
231bab81812Smycroft warnx("%s: not currently mounted", mntpt);
232bab81812Smycroft return (1);
23361f28255Scgd }
23498bd013cSpk break;
23598bd013cSpk default:
23656638e9dSlukem if ((name = getmntname(mntpt, MNTFROM, &type)) == NULL) {
237b4712500Sdsl name = mntpt;
23856638e9dSlukem if ((mntpt = getmntname(name, MNTON, &type)) == NULL) {
239655f1af4Spk warnx("%s: not currently mounted", name);
240ba0b3992Schristos return 1;
24161f28255Scgd }
242655f1af4Spk }
243655f1af4Spk }
24461f28255Scgd
245ba0b3992Schristos #ifndef SMALL
24656638e9dSlukem if (checkvfsname(type, typelist))
247ba0b3992Schristos return 1;
248bab81812Smycroft
249ba0b3992Schristos (void)memset(&hints, 0, sizeof hints);
25027e0d2b7Schristos if (!strncmp(type, MOUNT_NFS,
25127e0d2b7Schristos sizeof(((struct statvfs *)NULL)->f_fstypename))) {
2528cc28b4bSdsl char *delimp;
253958c0aacSchristos proto = getmntproto(mntpt);
254b4712500Sdsl /* look for host:mountpoint */
255b4712500Sdsl if ((delimp = strrchr(name, ':')) != NULL) {
2568cc28b4bSdsl int len = delimp - name;
2578cc28b4bSdsl hostp = malloc(len + 1);
2588cc28b4bSdsl if (hostp == NULL)
2598cc28b4bSdsl return 1;
2608cc28b4bSdsl memcpy(hostp, name, len);
2618cc28b4bSdsl hostp[len] = 0;
2628cc28b4bSdsl name += len + 1;
263ece47fa3Sdholland if (getaddrinfo(hostp, NULL, &hints, &ai) != 0)
264ece47fa3Sdholland ai = NULL;
26556638e9dSlukem }
26656638e9dSlukem }
26756638e9dSlukem
268d6548209Sfvdl if (!namematch(ai))
269ba0b3992Schristos return 1;
270ba0b3992Schristos #endif /* ! SMALL */
2714cc121caSdholland snprintf(umountprog, sizeof(umountprog), "umount_%s", type);
272383d022fSdholland }
2734cc121caSdholland
274ba0b3992Schristos #ifndef SMALL
2754cc121caSdholland if (verbose) {
276bab81812Smycroft (void)printf("%s: unmount from %s\n", name, mntpt);
2774cc121caSdholland /* put this before the test of FAKE */
2784cc121caSdholland if (!raw) {
2794cc121caSdholland (void)printf("Trying unmount program %s\n",
2804cc121caSdholland umountprog);
2814cc121caSdholland }
2824cc121caSdholland }
283bab81812Smycroft if (fake)
284ba0b3992Schristos return 0;
285ba0b3992Schristos #endif /* ! SMALL */
286bab81812Smycroft
2874cc121caSdholland if (!raw) {
2884cc121caSdholland /*
2894cc121caSdholland * The only options that need to be passed on are -f
2904cc121caSdholland * and -v.
2914cc121caSdholland */
2924cc121caSdholland char *args[3];
2934cc121caSdholland unsigned nargs = 0;
2944cc121caSdholland
2954cc121caSdholland args[nargs++] = umountprog;
2964cc121caSdholland if (fflag == MNT_FORCE) {
2974cc121caSdholland args[nargs++] = __UNCONST("-f");
2984cc121caSdholland }
2994cc121caSdholland #ifndef SMALL
3004cc121caSdholland if (verbose) {
3014cc121caSdholland args[nargs++] = __UNCONST("-v");
3024cc121caSdholland }
3034cc121caSdholland #endif
3044cc121caSdholland execvp(umountprog, args);
3054cc121caSdholland if (errno != ENOENT) {
3064cc121caSdholland warn("%s: execvp", umountprog);
3074cc121caSdholland }
3084cc121caSdholland }
3094cc121caSdholland
3104cc121caSdholland #ifndef SMALL
3114cc121caSdholland if (verbose)
3124cc121caSdholland (void)printf("(No separate unmount program.)\n");
3134cc121caSdholland #endif
3144cc121caSdholland
315704e0753Spooka if (unmount(mntpt, fflag) == -1) {
316bab81812Smycroft warn("%s", mntpt);
317ba0b3992Schristos return 1;
318bab81812Smycroft }
319bab81812Smycroft
320ba0b3992Schristos #ifndef SMALL
3218cc28b4bSdsl if (ai != NULL && !(fflag & MNT_FORCE)) {
322958c0aacSchristos clp = clnt_create(hostp, RPCPROG_MNT, RPCMNT_VER1, proto);
323d6548209Sfvdl if (clp == NULL) {
32461f28255Scgd clnt_pcreateerror("Cannot MNT PRC");
325ba0b3992Schristos return 1;
32661f28255Scgd }
327d6548209Sfvdl clp->cl_auth = authsys_create_default();
32861f28255Scgd try.tv_sec = 20;
32961f28255Scgd try.tv_usec = 0;
3302c6eadc9Schristos clnt_stat = clnt_call(clp, RPCMNT_UMOUNT, xdr_dir,
3312c6eadc9Schristos __UNCONST(name), xdr_void, NULL, try);
33261f28255Scgd if (clnt_stat != RPC_SUCCESS) {
33361f28255Scgd clnt_perror(clp, "Bad MNT RPC");
334ba0b3992Schristos return 1;
33561f28255Scgd }
33661f28255Scgd auth_destroy(clp->cl_auth);
33761f28255Scgd clnt_destroy(clp);
33861f28255Scgd }
339ba0b3992Schristos #endif /* ! SMALL */
340ba0b3992Schristos return 0;
34161f28255Scgd }
34261f28255Scgd
343ba0b3992Schristos static char *
getmntname(const char * name,mntwhat what,char ** type)344ff49552bSdsl getmntname(const char *name, mntwhat what, char **type)
34561f28255Scgd {
3466bd1d6d4Schristos static struct statvfs *mntbuf;
34756638e9dSlukem static int mntsize;
348*4efd5405Schristos static char mntfromname[MAXPATHLEN];
34956638e9dSlukem int i;
35061f28255Scgd
35156638e9dSlukem if (mntbuf == NULL &&
35256638e9dSlukem (mntsize = getmntinfo(&mntbuf, MNT_NOWAIT)) == 0) {
353bab81812Smycroft warn("getmntinfo");
354bab81812Smycroft return (NULL);
35561f28255Scgd }
3566403c86cSdrochner for (i = mntsize - 1; i >= 0; i--) {
357bab81812Smycroft if ((what == MNTON) && !strcmp(mntbuf[i].f_mntfromname, name)) {
358bab81812Smycroft if (type)
35956638e9dSlukem *type = mntbuf[i].f_fstypename;
36061f28255Scgd return (mntbuf[i].f_mntonname);
36161f28255Scgd }
362bab81812Smycroft if ((what == MNTFROM) && !strcmp(mntbuf[i].f_mntonname, name)) {
363bab81812Smycroft if (type)
36456638e9dSlukem *type = mntbuf[i].f_fstypename;
365*4efd5405Schristos if (getfsspecname(mntfromname, sizeof(mntfromname),
366*4efd5405Schristos mntbuf[i].f_mntfromname) == NULL)
367*4efd5405Schristos err(EXIT_FAILURE, "%s", mntfromname);
368*4efd5405Schristos return mntfromname;
36961f28255Scgd }
37061f28255Scgd }
371bab81812Smycroft return (NULL);
37261f28255Scgd }
37361f28255Scgd
374ba0b3992Schristos #ifndef SMALL
375ba0b3992Schristos static int
sacmp(const struct sockaddr * sa1,const struct sockaddr * sa2)376ff49552bSdsl sacmp(const struct sockaddr *sa1, const struct sockaddr *sa2)
37761f28255Scgd {
3782c6eadc9Schristos const void *p1, *p2;
3792c6eadc9Schristos size_t len;
38061f28255Scgd
381d6548209Sfvdl if (sa1->sa_family != sa2->sa_family)
382d6548209Sfvdl return 1;
383d6548209Sfvdl
384d6548209Sfvdl switch (sa1->sa_family) {
385d6548209Sfvdl case AF_INET:
3862c6eadc9Schristos p1 = &((const struct sockaddr_in *)sa1)->sin_addr;
3872c6eadc9Schristos p2 = &((const struct sockaddr_in *)sa2)->sin_addr;
388d6548209Sfvdl len = 4;
389d6548209Sfvdl break;
390d6548209Sfvdl case AF_INET6:
3912c6eadc9Schristos p1 = &((const struct sockaddr_in6 *)sa1)->sin6_addr;
3922c6eadc9Schristos p2 = &((const struct sockaddr_in6 *)sa2)->sin6_addr;
393d6548209Sfvdl len = 16;
3942c6eadc9Schristos if (((const struct sockaddr_in6 *)sa1)->sin6_scope_id !=
3952c6eadc9Schristos ((const struct sockaddr_in6 *)sa2)->sin6_scope_id)
396d6548209Sfvdl return 1;
397d6548209Sfvdl break;
398d6548209Sfvdl default:
399d6548209Sfvdl return 1;
400d6548209Sfvdl }
401d6548209Sfvdl
402d6548209Sfvdl return memcmp(p1, p2, len);
403d6548209Sfvdl }
404d6548209Sfvdl
405ba0b3992Schristos static int
namematch(const struct addrinfo * ai)406ff49552bSdsl namematch(const struct addrinfo *ai)
407d6548209Sfvdl {
408d6548209Sfvdl struct addrinfo *aip;
409d6548209Sfvdl
410d6548209Sfvdl if (nfshost == NULL || nfshost_ai == NULL)
41161f28255Scgd return (1);
412bab81812Smycroft
413d6548209Sfvdl while (ai != NULL) {
414d6548209Sfvdl aip = nfshost_ai;
415d6548209Sfvdl while (aip != NULL) {
416d6548209Sfvdl if (sacmp(ai->ai_addr, aip->ai_addr) == 0)
417d6548209Sfvdl return 1;
418d6548209Sfvdl aip = aip->ai_next;
419d6548209Sfvdl }
420d6548209Sfvdl ai = ai->ai_next;
421d6548209Sfvdl }
422bab81812Smycroft
423d6548209Sfvdl return 0;
42461f28255Scgd }
42561f28255Scgd
42661f28255Scgd /*
42761f28255Scgd * xdr routines for mount rpc's
42861f28255Scgd */
429ba0b3992Schristos static int
xdr_dir(XDR * xdrsp,char * dirp)430ff49552bSdsl xdr_dir(XDR *xdrsp, char *dirp)
43161f28255Scgd {
432ba0b3992Schristos return xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN);
43361f28255Scgd }
434da960e08Schristos
435da960e08Schristos static const char *
getmntproto(const char * name)436958c0aacSchristos getmntproto(const char *name)
437da960e08Schristos {
438da960e08Schristos struct nfs_args nfsargs;
439958c0aacSchristos struct sockaddr_storage ss;
440da960e08Schristos
441958c0aacSchristos nfsargs.sotype = SOCK_DGRAM;
442958c0aacSchristos nfsargs.addr = (struct sockaddr *)&ss;
443958c0aacSchristos nfsargs.addrlen = sizeof(ss);
444958c0aacSchristos (void)mount("nfs", name, MNT_GETARGS, &nfsargs, sizeof(nfsargs));
445958c0aacSchristos return nfsargs.sotype == SOCK_STREAM ? "tcp" : "udp";
446da960e08Schristos }
447ba0b3992Schristos #endif /* !SMALL */
448bab81812Smycroft
449ba0b3992Schristos static void
usage(void)450ff49552bSdsl usage(void)
451bab81812Smycroft {
452ba0b3992Schristos #ifdef SMALL
453bab81812Smycroft (void)fprintf(stderr,
454ba0b3992Schristos "Usage: %s [-fR] special | node\n", getprogname());
455ba0b3992Schristos #else
456ba0b3992Schristos (void)fprintf(stderr,
457ba0b3992Schristos "Usage: %s [-fvFR] [-t fstypelist] special | node\n"
458ba0b3992Schristos "\t %s -a[fvF] [-h host] [-t fstypelist]\n", getprogname(),
459ba0b3992Schristos getprogname());
460ba0b3992Schristos #endif /* SMALL */
461bab81812Smycroft exit(1);
462bab81812Smycroft }
463