+
+static
+prmount(spec, name, flags)
+ char *spec, *name;
+ register short flags;
+{
+ register int first;
+
+ if (opflags & ISBGRND)
+ return;
+ (void)printf("%s on %s", spec, name);
+ if (!(flags & MNT_VISFLAGMASK)) {
+ (void)printf("\n");
+ return;
+ }
+ first = 0;
+#define PR(msg) (void)printf("%s%s", !first++ ? " (" : ", ", msg)
+ if (flags & MNT_RDONLY)
+ PR("read-only");
+ if (flags & MNT_NOEXEC)
+ PR("noexec");
+ if (flags & MNT_NOSUID)
+ PR("nosuid");
+ if (flags & MNT_NODEV)
+ PR("nodev");
+ if (flags & MNT_SYNCHRONOUS)
+ PR("synchronous");
+ if (flags & MNT_QUOTA)
+ PR("with quotas");
+ if (flags & MNT_LOCAL)
+ PR("local");
+ if (flags & MNT_EXPORTED)
+ if (flags & MNT_EXRDONLY)
+ PR("NFS exported read-only");
+ else
+ PR("NFS exported");
+ (void)printf(")\n");
+}
+
+getmnttype(fstype)
+ char *fstype;
+{
+
+ mntname = fstype;
+ if (!strcmp(fstype, "ufs"))
+ return (MOUNT_UFS);
+ if (!strcmp(fstype, "nfs"))
+ return (MOUNT_NFS);
+ if (!strcmp(fstype, "mfs"))
+ return (MOUNT_MFS);
+ return (0);
+}
+
+usage()
+{
+
+ fprintf(stderr, "usage:\n mount %s %s\n mount %s\n mount %s\n",
+ "[ -frwu ] [ -t nfs | ufs | external_type ]",
+ "[ -o options ] special node",
+ "[ -afrwu ] [ -t nfs | ufs | external_type ]",
+ "[ -frwu ] special | node");
+ exit(1);
+}
+
+getstdopts(options, flagp)
+ char *options;
+ int *flagp;
+{
+ register char *opt;
+ int negative;
+ char optbuf[BUFSIZ];
+
+ (void)strcpy(optbuf, options);
+ for (opt = strtok(optbuf, ","); opt; opt = strtok((char *)NULL, ",")) {
+ if (opt[0] == 'n' && opt[1] == 'o') {
+ negative++;
+ opt += 2;
+ } else {
+ negative = 0;
+ }
+ if (!negative && !strcasecmp(opt, FSTAB_RO)) {
+ *flagp |= MNT_RDONLY;
+ continue;
+ }
+ if (!negative && !strcasecmp(opt, FSTAB_RW)) {
+ *flagp &= ~MNT_RDONLY;
+ continue;
+ }
+ if (!strcasecmp(opt, "exec")) {
+ if (negative)
+ *flagp |= MNT_NOEXEC;
+ else
+ *flagp &= ~MNT_NOEXEC;
+ continue;
+ }
+ if (!strcasecmp(opt, "suid")) {
+ if (negative)
+ *flagp |= MNT_NOSUID;
+ else
+ *flagp &= ~MNT_NOSUID;
+ continue;
+ }
+ if (!strcasecmp(opt, "dev")) {
+ if (negative)
+ *flagp |= MNT_NODEV;
+ else
+ *flagp &= ~MNT_NODEV;
+ continue;
+ }
+ if (!strcasecmp(opt, "synchronous")) {
+ if (!negative)
+ *flagp |= MNT_SYNCHRONOUS;
+ else
+ *flagp &= ~MNT_SYNCHRONOUS;
+ continue;
+ }
+ }
+}
+
+/* ARGSUSED */
+getufsopts(options, flagp)
+ char *options;
+ int *flagp;
+{
+ return;
+}
+
+getexecopts(options, argv)
+ char *options;
+ char **argv;
+{
+ register int argc = 0;
+ register char *opt;
+
+ for (opt = strtok(options, ","); opt; opt = strtok((char *)NULL, ",")) {
+ if (opt[0] != '-')
+ continue;
+ argv[argc++] = opt;
+ if (opt[2] == '\0' || opt[2] != '=')
+ continue;
+ opt[2] = '\0';
+ argv[argc++] = &opt[3];
+ }
+ return (argc);
+}
+
+struct statfs *
+getmntpt(name)
+ char *name;
+{
+ long mntsize;
+ register long i;
+ struct statfs *mntbuf;
+
+ mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
+ for (i = 0; i < mntsize; i++) {
+ if (!strcmp(mntbuf[i].f_mntfromname, name) ||
+ !strcmp(mntbuf[i].f_mntonname, name))
+ return (&mntbuf[i]);
+ }
+ return ((struct statfs *)0);
+}
+
+static int skipvfs;
+
+badvfstype(vfstype, vfslist)
+ short vfstype;
+ char **vfslist;
+{
+
+ if (vfslist == 0)
+ return(0);
+ while (*vfslist) {
+ if (vfstype == getmnttype(*vfslist))
+ return(skipvfs);
+ vfslist++;
+ }
+ return (!skipvfs);
+}
+
+badvfsname(vfsname, vfslist)
+ char *vfsname;
+ char **vfslist;
+{
+
+ if (vfslist == 0)
+ return(0);
+ while (*vfslist) {
+ if (strcmp(vfsname, *vfslist) == 0)
+ return(skipvfs);
+ vfslist++;
+ }
+ return (!skipvfs);
+}
+
+char **
+makevfslist(fslist)
+ char *fslist;
+{
+ register char **av, *nextcp;
+ register int i;
+
+ if (fslist == NULL)
+ return (NULL);
+ if (fslist[0] == 'n' && fslist[1] == 'o') {
+ fslist += 2;
+ skipvfs = 1;
+ }
+ for (i = 0, nextcp = fslist; *nextcp; nextcp++)
+ if (*nextcp == ',')
+ i++;
+ av = (char **)malloc((size_t)(i+2) * sizeof(char *));
+ if (av == NULL)
+ return (NULL);
+ nextcp = fslist;
+ i = 0;
+ av[i++] = nextcp;
+ while (nextcp = index(nextcp, ',')) {
+ *nextcp++ = '\0';
+ av[i++] = nextcp;
+ }
+ av[i++] = 0;
+ return (av);
+}
+
+#ifdef NFS
+/*
+ * Handle the getoption arg.
+ * Essentially update "opflags", "retrycnt" and "nfsargs"
+ */
+getnfsopts(optarg, nfsargsp, opflagsp, retrycntp)
+ char *optarg;
+ struct nfs_args *nfsargsp;
+ int *opflagsp;
+ int *retrycntp;
+{
+ register char *cp, *nextcp;
+ int num;
+ char *nump;
+
+ cp = optarg;
+ while (cp != NULL && *cp != '\0') {
+ if ((nextcp = index(cp, ',')) != NULL)
+ *nextcp++ = '\0';
+ if ((nump = index(cp, '=')) != NULL) {
+ *nump++ = '\0';
+ num = atoi(nump);
+ } else
+ num = -1;
+ /*
+ * Just test for a string match and do it
+ */
+ if (!strcmp(cp, "bg")) {
+ *opflagsp |= BGRND;
+ } else if (!strcmp(cp, "soft")) {
+ if (nfsargsp->flags & NFSMNT_SPONGY) {
+ fprintf(stderr,
+ "Options soft, spongy mutually exclusive\n");
+ exit(1);
+ }
+ nfsargsp->flags |= NFSMNT_SOFT;
+ } else if (!strcmp(cp, "spongy")) {
+ if (nfsargsp->flags & NFSMNT_SOFT) {
+ fprintf(stderr,
+ "Options soft, spongy mutually exclusive\n");
+ exit(1);
+ }
+ nfsargsp->flags |= NFSMNT_SPONGY;
+ } else if (!strcmp(cp, "intr")) {
+ nfsargsp->flags |= NFSMNT_INT;
+ } else if (!strcmp(cp, "tcp")) {
+ nfsargsp->sotype = SOCK_STREAM;
+ } else if (!strcmp(cp, "noconn")) {
+ nfsargsp->flags |= NFSMNT_NOCONN;
+ } else if (!strcmp(cp, "retry") && num > 0) {
+ *retrycntp = num;
+ } else if (!strcmp(cp, "rsize") && num > 0) {
+ nfsargsp->rsize = num;
+ nfsargsp->flags |= NFSMNT_RSIZE;
+ } else if (!strcmp(cp, "wsize") && num > 0) {
+ nfsargsp->wsize = num;
+ nfsargsp->flags |= NFSMNT_WSIZE;
+ } else if (!strcmp(cp, "timeo") && num > 0) {
+ nfsargsp->timeo = num;
+ nfsargsp->flags |= NFSMNT_TIMEO;
+ } else if (!strcmp(cp, "retrans") && num > 0) {
+ nfsargsp->retrans = num;
+ nfsargsp->flags |= NFSMNT_RETRANS;
+ }
+ cp = nextcp;
+ }
+ if (nfsargsp->sotype == SOCK_DGRAM) {
+ if (nfsargsp->rsize > NFS_MAXDGRAMDATA)
+ nfsargsp->rsize = NFS_MAXDGRAMDATA;
+ if (nfsargsp->wsize > NFS_MAXDGRAMDATA)
+ nfsargsp->wsize = NFS_MAXDGRAMDATA;
+ }
+}
+
+char *
+getnfsargs(spec, nfsargsp)
+ char *spec;
+ struct nfs_args *nfsargsp;
+{
+ extern int errno;
+ register CLIENT *clp;
+ struct hostent *hp;
+ static struct sockaddr_in saddr;
+ struct timeval pertry, try;
+ enum clnt_stat clnt_stat;
+ int so = RPC_ANYSOCK;
+ char *hostp, *delimp;
+ u_short tport;
+ static struct nfhret nfhret;
+ static char nam[MNAMELEN + 1];
+
+ strncpy(nam, spec, MNAMELEN);
+ nam[MNAMELEN] = '\0';
+ if ((delimp = index(spec, '@')) != NULL) {
+ hostp = delimp + 1;
+ } else if ((delimp = index(spec, ':')) != NULL) {
+ hostp = spec;
+ spec = delimp + 1;
+ } else {
+ fprintf(stderr,
+ "No <host>:<dirpath> or <dirpath>@<host> spec\n");
+ return (0);
+ }
+ *delimp = '\0';
+ if ((hp = gethostbyname(hostp)) == NULL) {
+ fprintf(stderr, "Can't get net id for host\n");
+ return (0);
+ }
+ bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length);
+ nfhret.stat = EACCES; /* Mark not yet successful */
+ while (retrycnt > 0) {
+ 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");
+ } else {
+ saddr.sin_port = 0;
+ pertry.tv_sec = 10;
+ pertry.tv_usec = 0;
+ if ((clp = clntudp_create(&saddr, RPCPROG_MNT,
+ RPCMNT_VER1, pertry, &so)) == NULL) {
+ if ((opflags & ISBGRND) == 0)
+ clnt_pcreateerror("Cannot MNT PRC");
+ } else {
+ clp->cl_auth = authunix_create_default();
+ try.tv_sec = 10;
+ try.tv_usec = 0;
+ 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");
+ } else {
+ auth_destroy(clp->cl_auth);
+ clnt_destroy(clp);
+ retrycnt = 0;
+ }
+ }
+ }
+ if (--retrycnt > 0) {
+ if (opflags & BGRND) {
+ opflags &= ~BGRND;
+ if (fork())
+ return (0);
+ else
+ opflags |= ISBGRND;
+ }
+ sleep(10);
+ }
+ }
+ if (nfhret.stat) {
+ if (opflags & ISBGRND)
+ exit(1);
+ fprintf(stderr, "Can't access %s: ", spec);
+ errno = nfhret.stat;
+ perror((char *)NULL);
+ return (0);
+ }
+ saddr.sin_port = htons(tport);
+ nfsargsp->addr = (struct sockaddr *) &saddr;
+ nfsargsp->fh = &nfhret.nfh;
+ nfsargsp->hostname = nam;
+ return ((caddr_t)nfsargsp);
+}
+
+/*
+ * xdr routines for mount rpc's
+ */
+xdr_dir(xdrsp, dirp)
+ XDR *xdrsp;
+ char *dirp;
+{
+ return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
+}
+
+xdr_fh(xdrsp, np)
+ XDR *xdrsp;
+ struct nfhret *np;
+{
+ if (!xdr_u_long(xdrsp, &(np->stat)))
+ return (0);
+ if (np->stat)
+ return (1);
+ return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH));
+}
+#endif /* NFS */