* Copyright (c) 1980, 1989 The Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1980, 1989 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)mount.c 5.25 (Berkeley) %G%";
#include <sys/socketvar.h>
#include <rpc/pmap_clnt.h>
#include <rpc/pmap_prot.h>
(strcmp(type, FSTAB_RO) && strcmp(type, FSTAB_RW) && \
(!strcmp(type, FSTAB_RW) || !strcmp(type, FSTAB_RQ))
int fake
, verbose
, updateflg
, mnttype
;
char **vfslist
, **makevfslist();
struct nfs_args nfsargs
= {
register struct fstab
*fs
;
int all
, ch
, rval
, flags
, i
;
struct statfs
*mntbuf
, *getmntpt();
char *type
, *options
= NULL
;
while ((ch
= getopt(argc
, argv
, "afrwuvt:o:")) != EOF
)
vfslist
= makevfslist(optarg
);
mnttype
= getmnttype(optarg
);
while (fs
= getfsent()) {
if (BADTYPE(fs
->fs_type
))
if (badvfstype(fs
->fs_vfstype
, vfslist
))
/* `/' is special, it's always mounted */
if (!strcmp(fs
->fs_file
, "/"))
mnttype
= getmnttype(fs
->fs_vfstype
);
rval
|= mountfs(fs
->fs_spec
, fs
->fs_file
, flags
,
type
, options
, fs
->fs_mntops
);
if (verbose
|| fake
|| type
)
if ((mntsize
= getmntinfo(&mntbuf
)) == 0) {
"mount: cannot get mount information\n");
for (i
= 0; i
< mntsize
; i
++)
prmount(mntbuf
[i
].f_mntfromname
, mntbuf
[i
].f_mntonname
,
if (argc
== 1 && updateflg
) {
if ((mntbuf
= getmntpt(*argv
)) == NULL
) {
"mount: unknown special file or file system %s.\n",
mnttype
= mntbuf
->f_type
;
if (!strcmp(mntbuf
->f_mntfromname
, "root_device")) {
strcpy(mntbuf
->f_mntfromname
, fs
->fs_spec
);
exit(mountfs(mntbuf
->f_mntfromname
, mntbuf
->f_mntonname
,
updateflg
, type
, options
, NULL
));
if (!(fs
= getfsfile(*argv
)) && !(fs
= getfsspec(*argv
))) {
"mount: unknown special file or file system %s.\n",
if (BADTYPE(fs
->fs_type
)) {
"mount: %s has unknown file system type.\n", *argv
);
mnttype
= getmnttype(fs
->fs_vfstype
);
exit(mountfs(fs
->fs_spec
, fs
->fs_file
, updateflg
,
type
, options
, fs
->fs_mntops
));
exit(mountfs(argv
[0], argv
[1], updateflg
, type
, options
, NULL
));
mountfs(spec
, name
, flags
, type
, options
, mntopts
)
char *spec
, *name
, *type
, *options
, *mntopts
;
char execname
[MAXPATHLEN
+ 1], flagval
[12];
getstdopts(mntopts
, &flags
);
getstdopts(options
, &flags
);
getstdopts(type
, &flags
);
getufsopts(mntopts
, &flags
);
getufsopts(options
, &flags
);
getnfsopts(mntopts
, &nfsargs
, &opflags
, &retrycnt
);
getnfsopts(options
, &nfsargs
, &opflags
, &retrycnt
);
if (argp
= getnfsargs(spec
, name
, type
))
sprintf(flagval
, "%d", flags
);
argc
+= getexecopts(mntopts
, &argv
[argc
]);
argc
+= getexecopts(options
, &argv
[argc
]);
sprintf(execname
, "%s/mount_%s", _PATH_EXECDIR
, mntname
);
printf("exec: %s", execname
);
for (i
= 1; i
< argc
; i
++)
perror("mount: vfork starting file system");
if (waitpid(i
, &status
, 0) != -1 &&
WEXITSTATUS(status
) != 0)
return (WEXITSTATUS(status
));
execve(execname
, argv
, envp
);
fprintf(stderr
, "mount: cannot exec %s for %s: ",
if (!fake
&& mount(mnttype
, name
, flags
, argp
)) {
fprintf(stderr
, "%s on %s: ", spec
, name
);
fprintf(stderr
, "Mount table full\n");
fprintf(stderr
, "Specified device does %s\n",
"not match mounted device");
fprintf(stderr
, "Bogus super block\n");
fprintf(stderr
, "Operation not supported\n");
prmount(spec
, name
, flags
);
prmount(spec
, name
, flags
)
* trim trailing /'s and find last component of name
for (root
= index(spec
, '\0'); *--root
== '/';)
if (root
= rindex(spec
, '/'))
printf("%s on %s", spec
, name
);
if (flags
& M_SYNCHRONOUS
)
printf(" (synchronous)");
printf(" (update only)");
if (!strcmp(fstype
, "ufs"))
if (!strcmp(fstype
, "nfs"))
if (!strcmp(fstype
, "mfs"))
fprintf(stderr
, "usage: mount [-afurw]\nor mount [-furw] special | node\nor mount [-furw] special node\n");
getstdopts(options
, flagp
)
char *optbuf
[BUFSIZ
], *strtok();
for (opt
= strtok(optbuf
, ","); opt
; opt
= strtok(NULL
, ",")) {
if (opt
[0] == 'n' && opt
[1] == 'o') {
if (!negative
&& !strcasecmp(opt
, FSTAB_RO
)) {
if (!negative
&& !strcasecmp(opt
, FSTAB_RW
)) {
if (!strcasecmp(opt
, "exec")) {
if (!strcasecmp(opt
, "suid")) {
if (!strcasecmp(opt
, "dev")) {
if (!strcasecmp(opt
, "synchronous")) {
*flagp
&= ~M_SYNCHRONOUS
;
getufsopts(options
, flagp
)
getexecopts(options
, argv
)
for (opt
= strtok(options
, ","); opt
; opt
= strtok(NULL
, ",")) {
if (opt
[2] == '\0' || opt
[2] != '=')
mntsize
= getmntinfo(&mntbuf
);
for (i
= 0; i
< mntsize
; i
++) {
if (!strcmp(mntbuf
[i
].f_mntfromname
, name
) ||
!strcmp(mntbuf
[i
].f_mntonname
, name
))
return ((struct statfs
*)0);
badvfstype(vfstype
, vfslist
)
if (strcmp(vfstype
, *vfslist
) == 0)
register char **av
, *nextcp
;
if (fslist
[0] == 'n' && fslist
[1] == 'o') {
for (i
= 0, nextcp
= fslist
; *nextcp
; nextcp
++)
av
= (char **)malloc((i
+2) * sizeof(char *));
while (nextcp
= index(nextcp
, ',')) {
* Handle the getoption arg.
* Essentially update "opflags", "retrycnt" and "nfsargs"
getnfsopts(optarg
, nfsargsp
, opflagsp
, retrycntp
)
struct nfs_args
*nfsargsp
;
register char *cp
, *nextcp
;
while (cp
!= NULL
&& *cp
!= '\0') {
if ((nextcp
= index(cp
, ',')) != NULL
)
if ((nump
= index(cp
, '=')) != NULL
) {
* Just test for a string match and do it
} else if (!strcmp(cp
, "soft")) {
nfsargsp
->flags
|= NFSMNT_SOFT
;
} else if (!strcmp(cp
, "intr")) {
nfsargsp
->flags
|= NFSMNT_INT
;
} else if (!strcmp(cp
, "retry") && num
> 0) {
} else if (!strcmp(cp
, "rsize") && num
> 0) {
nfsargsp
->flags
|= NFSMNT_RSIZE
;
} else if (!strcmp(cp
, "wsize") && num
> 0) {
nfsargsp
->flags
|= NFSMNT_WSIZE
;
} else if (!strcmp(cp
, "timeo") && num
> 0) {
nfsargsp
->flags
|= NFSMNT_TIMEO
;
} else if (!strcmp(cp
, "retrans") && num
> 0) {
nfsargsp
->flags
|= NFSMNT_RETRANS
;
static struct sockaddr_in saddr
;
struct timeval pertry
, try;
enum clnt_stat clnt_stat
;
static struct nfhret nfhret
;
static char nam
[MNAMELEN
+ 1];
strncpy(nam
, spec
, MNAMELEN
);
if ((delimp
= index(spec
, '@')) != NULL
) {
} else if ((delimp
= index(spec
, ':')) != NULL
) {
"No <host>:<dirpath> or <dirpath>@<host> spec\n");
if ((hp
= gethostbyname(hostp
)) == NULL
) {
fprintf(stderr
, "Can't get net id for host\n");
bcopy(hp
->h_addr
, (caddr_t
)&saddr
.sin_addr
, hp
->h_length
);
nfhret
.stat
= EACCES
; /* Mark not yet successful */
saddr
.sin_family
= AF_INET
;
saddr
.sin_port
= htons(PMAPPORT
);
if ((tport
= pmap_getport(&saddr
, RPCPROG_NFS
,
NFS_VER2
, IPPROTO_UDP
)) == 0) {
if ((opflags
& ISBGRND
) == 0)
clnt_pcreateerror("NFS Portmap");
if ((clp
= clntudp_create(&saddr
, RPCPROG_MNT
,
RPCMNT_VER1
, pertry
, &so
)) == NULL
) {
if ((opflags
& ISBGRND
) == 0)
clnt_pcreateerror("Cannot MNT PRC");
clp
->cl_auth
= authunix_create_default();
clnt_stat
= clnt_call(clp
, RPCMNT_MOUNT
,
xdr_dir
, spec
, xdr_fh
, &nfhret
, try);
if (clnt_stat
!= RPC_SUCCESS
) {
if ((opflags
& ISBGRND
) == 0)
clnt_perror(clp
, "Bad MNT RPC");
auth_destroy(clp
->cl_auth
);
fprintf(stderr
, "Can't access %s: ", spec
);
saddr
.sin_port
= htons(tport
);
nfsargs
.fh
= &nfhret
.nfh
;
return ((caddr_t
)&nfsargs
);
* xdr routines for mount rpc's
return (xdr_string(xdrsp
, &dirp
, RPCMNT_PATHLEN
));
if (!xdr_u_long(xdrsp
, &(np
->stat
)))
return (xdr_opaque(xdrsp
, (caddr_t
)&(np
->nfh
), NFSX_FH
));