+
+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 */