2c3b0aded78c1756fae6f8b7ba0e0c01f66f3250
* Copyright (c) 1980, 1989, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
static char copyright
[] =
"@(#) Copyright (c) 1980, 1989, 1993\n\
The Regents of the University of California. All rights reserved.\n";
static char sccsid
[] = "@(#)umount.c 8.5 (Berkeley) %G%";
#include <sys/socketvar.h>
#include <rpc/pmap_clnt.h>
#include <rpc/pmap_prot.h>
typedef enum { MNTON
, MNTFROM
} mntwhat
;
int fake
, fflag
, vflag
, *typelist
;
int fsnametotype
__P((char *));
char *getmntname
__P((char *, mntwhat
, int *));
void maketypelist
__P((char *));
int namematch
__P((struct hostent
*));
int umountall
__P((void));
int umountfs
__P((char *));
int xdr_dir
__P((XDR
*, char *));
/* Start disks transferring immediately. */
while ((ch
= getopt(argc
, argv
, "aFfh:t:v")) != EOF
)
case 'h': /* -h implies -a. */
if (argc
== 0 && !all
|| argc
!= 0 && all
)
/* -h implies "-t nfs" if no -t flag. */
if ((nfshost
!= NULL
) && (typelist
== NULL
))
err(1, "%s", _PATH_FSTAB
);
for (errs
= 0; *argv
!= NULL
; ++argv
)
if (umountfs(*argv
) != 0)
while ((fs
= getfsent()) != NULL
) {
if (strcmp(fs
->fs_file
, "/") == 0)
* Historic practice: ignore unknown FSTAB_* fields.
if (strcmp(fs
->fs_type
, FSTAB_RW
) &&
strcmp(fs
->fs_type
, FSTAB_RO
) &&
strcmp(fs
->fs_type
, FSTAB_RQ
))
/* If an unknown file system type, complain. */
if ((type
= fsnametotype(fs
->fs_vfstype
)) == MOUNT_NONE
) {
warnx("%s: unknown mount type", fs
->fs_vfstype
);
* We want to unmount the file systems in the reverse order
* that they were mounted. So, we save off the file name
* in some allocated memory, and then call recursively.
if ((cp
= malloc((size_t)strlen(fs
->fs_file
) + 1)) == NULL
)
(void)strcpy(cp
, fs
->fs_file
);
return (umountfs(cp
) || rval
);
enum clnt_stat clnt_stat
;
struct sockaddr_in saddr
;
struct timeval pertry
, try;
char *delimp
, *hostp
, *mntpt
, rname
[MAXPATHLEN
];
if (realpath(name
, rname
) == NULL
) {
if (stat(name
, &sb
) < 0) {
if (((mntpt
= getmntname(name
, MNTFROM
, &type
)) == NULL
) &&
((mntpt
= getmntname(name
, MNTON
, &type
)) == NULL
)) {
warnx("%s: not currently mounted", name
);
} else if (S_ISBLK(sb
.st_mode
)) {
if ((mntpt
= getmntname(name
, MNTON
, &type
)) == NULL
) {
warnx("%s: not currently mounted", name
);
} else if (S_ISDIR(sb
.st_mode
)) {
if ((name
= getmntname(mntpt
, MNTFROM
, &type
)) == NULL
) {
warnx("%s: not currently mounted", mntpt
);
warnx("%s: not a directory or special device", name
);
if ((delimp
= strchr(name
, '@')) != NULL
) {
hp
= gethostbyname(hostp
);
} else if ((delimp
= strchr(name
, ':')) != NULL
) {
hp
= gethostbyname(hostp
);
(void)printf("%s: unmount from %s\n", name
, mntpt
);
if (unmount(mntpt
, fflag
) < 0) {
if ((hp
!= NULL
) && !(fflag
& MNT_FORCE
)) {
memset(&saddr
, 0, sizeof(saddr
));
saddr
.sin_family
= AF_INET
;
memmove(&saddr
.sin_addr
, hp
->h_addr
, hp
->h_length
);
if ((clp
= clntudp_create(&saddr
,
RPCPROG_MNT
, RPCMNT_VER1
, pertry
, &so
)) == NULL
) {
clnt_pcreateerror("Cannot MNT PRC");
clp
->cl_auth
= authunix_create_default();
clnt_stat
= clnt_call(clp
,
RPCMNT_UMOUNT
, xdr_dir
, name
, xdr_void
, (caddr_t
)0, try);
if (clnt_stat
!= RPC_SUCCESS
) {
clnt_perror(clp
, "Bad MNT RPC");
auth_destroy(clp
->cl_auth
);
getmntname(name
, what
, type
)
if ((mntsize
= getmntinfo(&mntbuf
, MNT_NOWAIT
)) == 0) {
for (i
= 0; i
< mntsize
; i
++) {
if ((what
== MNTON
) && !strcmp(mntbuf
[i
].f_mntfromname
, name
)) {
*type
= mntbuf
[i
].f_type
;
return (mntbuf
[i
].f_mntonname
);
if ((what
== MNTFROM
) && !strcmp(mntbuf
[i
].f_mntonname
, name
)) {
*type
= mntbuf
[i
].f_type
;
return (mntbuf
[i
].f_mntfromname
);
static enum { IN_LIST
, NOT_IN_LIST
} which
;
/* If no type specified, it's always selected. */
for (av
= typelist
; *av
!= NULL
; ++av
)
return (which
== IN_LIST
? 1 : 0);
return (which
== IN_LIST
? 0 : 1);
if ((fslist
== NULL
) || (fslist
[0] == '\0'))
errx(1, "empty type list");
* Note: the syntax is "noxxx,yyy" for no xxx's and
* no yyy's, not the more intuitive "noyyy,noyyy".
if (fslist
[0] == 'n' && fslist
[1] == 'o') {
/* Count the number of types. */
for (i
= 0, nextcp
= fslist
; *nextcp
!= NULL
; ++nextcp
)
/* Build an array of that many types. */
if ((av
= typelist
= malloc((i
+ 2) * sizeof(int))) == NULL
)
for (i
= 0; fslist
!= NULL
; fslist
= nextcp
, ++i
) {
if ((nextcp
= strchr(fslist
, ',')) != NULL
)
av
[i
] = fsnametotype(fslist
);
errx(1, "%s: unknown mount type", fslist
);
/* Terminate the array. */
static char const *namelist
[] = INITMOUNTNAMES
;
for (cp
= namelist
; *cp
; ++cp
)
if (strcmp(name
, *cp
) == 0)
if ((hp
== NULL
) || (nfshost
== NULL
))
if (strcasecmp(nfshost
, hp
->h_name
) == 0)
if ((cp
= strchr(hp
->h_name
, '.')) != NULL
) {
if (strcasecmp(nfshost
, hp
->h_name
) == 0)
for (np
= hp
->h_aliases
; *np
; np
++) {
if (strcasecmp(nfshost
, *np
) == 0)
if ((cp
= strchr(*np
, '.')) != NULL
) {
if (strcasecmp(nfshost
, *np
) == 0)
* xdr routines for mount rpc's
return (xdr_string(xdrsp
, &dirp
, RPCMNT_PATHLEN
));
"umount [-fv] [-t fstypelist] special | node",
"umount -a[fv] [-h host] [-t fstypelist]");