* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
static char sccsid
[] = "@(#)mount.c 5.14 (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))
static int fake
, verbose
, mnttype
;
struct nfs_args nfsargs
= {
register struct fstab
*fs
;
int all
, ch
, rval
, sfake
, i
;
char *type
, *options
= NULL
;
while ((ch
= getopt(argc
, argv
, "afrwvt:o:")) != EOF
)
if (mnttype
= getmnttype(optarg
))
for (sfake
= fake
; fs
= getfsent(); fake
= sfake
) {
if (BADTYPE(fs
->fs_type
))
/* `/' is special, it's always mounted */
if (!strcmp(fs
->fs_file
, "/"))
if ((mnttype
= getmnttype(fs
->fs_vfstype
)) == 0) {
"%s %s type of file system is unknown.\n",
"mount:", fs
->fs_vfstype
);
rval
|= mountfs(fs
->fs_spec
, fs
->fs_file
,
type
? type
: fs
->fs_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 (!(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
);
if ((mnttype
= getmnttype(fs
->fs_vfstype
)) == 0) {
"mount: %s type of file system is unknown.\n",
exit(mountfs(fs
->fs_spec
, fs
->fs_file
,
type
? type
: fs
->fs_type
, options
, fs
->fs_mntops
));
exit(mountfs(argv
[0], argv
[1], type
? type
: "rw", options
, NULL
));
mountfs(spec
, name
, type
, options
, mntopts
)
char *spec
, *name
, *type
, *options
, *mntopts
;
int flags
, argc
, status
, i
;
if (!strcmp(type
, FSTAB_RO
))
getstdopts(options
, &flags
);
getstdopts(mntopts
, &flags
);
getufsopts(options
, &flags
);
getufsopts(mntopts
, &flags
);
getnfsopts(options
, &nfsargs
, &opflags
,
getnfsopts(mntopts
, &nfsargs
, &opflags
,
if (argp
= getnfsargs(spec
, name
, type
))
argc
+= getmfsopts(options
, &argv
[argc
]);
argc
+= getmfsopts(mntopts
, &argv
[argc
]);
for (i
= 0; i
< argc
; i
++)
perror("mount: vfork for memfs");
if (waitpid(i
, &status
, 0) != -1 &&
WEXITSTATUS(status
) != 0)
return (WEXITSTATUS(status
));
execve(_PATH_MEMFS
, argv
, envp
);
fprintf(stderr
, "%d: unknown mount type\n", mnttype
);
if (!fake
&& mount(mnttype
, name
, flags
, argp
)) {
fprintf(stderr
, "%s on %s: ", spec
, name
);
fprintf(stderr
, "Mount table full\n");
fprintf(stderr
, "Bogus super block\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)");
if (!strcmp(fstype
, "ufs"))
if (!strcmp(fstype
, "nfs"))
if (!strcmp(fstype
, "mfs"))
fprintf(stderr
, "usage: mount [-afrw]\nor mount [-frw] special | node\nor mount [-frw] 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 (!strcasecmp(opt
, "exec")) {
if (!strcasecmp(opt
, "suid")) {
if (!strcasecmp(opt
, "dev")) {
if (!strcasecmp(opt
, "synchronous")) {
getufsopts(options
, flagp
)
getmfsopts(options
, argv
)
for (opt
= strtok(options
, ","); opt
; opt
= strtok(NULL
, ",")) {
if (opt
[2] == '\0' || opt
[2] != '=')
* 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
;
struct sockaddr_in saddr
;
struct timeval pertry
, try;
enum clnt_stat clnt_stat
;
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, errno=%d\n", 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
));