mount_nfs.c revision 2776
11558Srgrimes/* 21558Srgrimes * Copyright (c) 1992, 1993, 1994 31558Srgrimes * The Regents of the University of California. All rights reserved. 41558Srgrimes * 51558Srgrimes * This code is derived from software contributed to Berkeley by 61558Srgrimes * Rick Macklem at The University of Guelph. 71558Srgrimes * 81558Srgrimes * Redistribution and use in source and binary forms, with or without 91558Srgrimes * modification, are permitted provided that the following conditions 101558Srgrimes * are met: 111558Srgrimes * 1. Redistributions of source code must retain the above copyright 121558Srgrimes * notice, this list of conditions and the following disclaimer. 131558Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141558Srgrimes * notice, this list of conditions and the following disclaimer in the 151558Srgrimes * documentation and/or other materials provided with the distribution. 161558Srgrimes * 3. All advertising materials mentioning features or use of this software 171558Srgrimes * must display the following acknowledgement: 181558Srgrimes * This product includes software developed by the University of 191558Srgrimes * California, Berkeley and its contributors. 201558Srgrimes * 4. Neither the name of the University nor the names of its contributors 211558Srgrimes * may be used to endorse or promote products derived from this software 221558Srgrimes * without specific prior written permission. 231558Srgrimes * 241558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341558Srgrimes * SUCH DAMAGE. 351558Srgrimes */ 361558Srgrimes 371558Srgrimes#ifndef lint 381558Srgrimesstatic char copyright[] = 391558Srgrimes"@(#) Copyright (c) 1992, 1993, 1994\n\ 401558Srgrimes The Regents of the University of California. All rights reserved.\n"; 411558Srgrimes#endif /* not lint */ 421558Srgrimes 431558Srgrimes#ifndef lint 441558Srgrimesstatic char sccsid[] = "@(#)mount_nfs.c 8.3 (Berkeley) 3/27/94"; 451558Srgrimes#endif /* not lint */ 461558Srgrimes 471558Srgrimes#include <sys/param.h> 481558Srgrimes#include <sys/mount.h> 491558Srgrimes#include <sys/socket.h> 501558Srgrimes#include <sys/socketvar.h> 511558Srgrimes#include <sys/stat.h> 521558Srgrimes#include <sys/syslog.h> 531558Srgrimes 541558Srgrimes#include <rpc/rpc.h> 551558Srgrimes#include <rpc/pmap_clnt.h> 561558Srgrimes#include <rpc/pmap_prot.h> 571558Srgrimes 581558Srgrimes#ifdef ISO 591558Srgrimes#include <netiso/iso.h> 601558Srgrimes#endif 611558Srgrimes 621558Srgrimes#ifdef KERBEROS 631558Srgrimes#include <kerberosIV/des.h> 641558Srgrimes#include <kerberosIV/krb.h> 651558Srgrimes#endif 661558Srgrimes 671558Srgrimes#include <nfs/rpcv2.h> 681558Srgrimes#include <nfs/nfsv2.h> 691558Srgrimes#define KERNEL 701558Srgrimes#include <nfs/nfs.h> 711558Srgrimes#undef KERNEL 721558Srgrimes#include <nfs/nqnfs.h> 731558Srgrimes 741558Srgrimes#include <arpa/inet.h> 751558Srgrimes 761558Srgrimes#include <ctype.h> 771558Srgrimes#include <err.h> 781558Srgrimes#include <errno.h> 791558Srgrimes#include <fcntl.h> 801558Srgrimes#include <netdb.h> 811558Srgrimes#include <signal.h> 821558Srgrimes#include <stdio.h> 831558Srgrimes#include <stdlib.h> 841558Srgrimes#include <strings.h> 851558Srgrimes#include <unistd.h> 861558Srgrimes 871558Srgrimes#include "mntopts.h" 881558Srgrimes 891558Srgrimesstruct mntopt mopts[] = { 901558Srgrimes MOPT_STDOPTS, 911558Srgrimes MOPT_FORCE, 921558Srgrimes MOPT_UPDATE, 931558Srgrimes { NULL } 941558Srgrimes}; 951558Srgrimes 961558Srgrimesstruct nfs_args nfsdefargs = { 971558Srgrimes (struct sockaddr *)0, 981558Srgrimes sizeof (struct sockaddr_in), 991558Srgrimes SOCK_DGRAM, 1001558Srgrimes 0, 1011558Srgrimes (nfsv2fh_t *)0, 1021558Srgrimes 0, 1031558Srgrimes NFS_WSIZE, 1041558Srgrimes NFS_RSIZE, 1051558Srgrimes NFS_TIMEO, 1061558Srgrimes NFS_RETRANS, 1071558Srgrimes NFS_MAXGRPS, 1081558Srgrimes NFS_DEFRAHEAD, 1091558Srgrimes NQ_DEFLEASE, 1101558Srgrimes NQ_DEADTHRESH, 1111558Srgrimes (char *)0, 1121558Srgrimes}; 1131558Srgrimes 1141558Srgrimesstruct nfhret { 1151558Srgrimes u_long stat; 1161558Srgrimes nfsv2fh_t nfh; 1171558Srgrimes}; 1181558Srgrimes#define DEF_RETRY 10000 1191558Srgrimes#define BGRND 1 1201558Srgrimes#define ISBGRND 2 1211558Srgrimesint retrycnt = DEF_RETRY; 1221558Srgrimesint opflags = 0; 1231558Srgrimes 1241558Srgrimes#ifdef KERBEROS 1251558Srgrimeschar inst[INST_SZ]; 1261558Srgrimeschar realm[REALM_SZ]; 1271558SrgrimesKTEXT_ST kt; 1281558Srgrimes#endif 1291558Srgrimes 1301558Srgrimesint getnfsargs __P((char *, struct nfs_args *)); 1311558Srgrimes#ifdef ISO 1321558Srgrimesstruct iso_addr *iso_addr __P((const char *)); 1331558Srgrimes#endif 1341558Srgrimesvoid set_rpc_maxgrouplist __P((int)); 1351558Srgrimes__dead void usage __P((void)); 1361558Srgrimesint xdr_dir __P((XDR *, char *)); 1371558Srgrimesint xdr_fh __P((XDR *, struct nfhret *)); 1381558Srgrimes 1391558Srgrimesint 1401558Srgrimesmain(argc, argv) 1411558Srgrimes int argc; 1421558Srgrimes char *argv[]; 1431558Srgrimes{ 1441558Srgrimes register int c; 1451558Srgrimes register struct nfs_args *nfsargsp; 1461558Srgrimes struct nfs_args nfsargs; 1471558Srgrimes struct nfsd_cargs ncd; 1481558Srgrimes int mntflags, i, nfssvc_flag, num; 1491558Srgrimes char *name, *p, *spec; 1501558Srgrimes int error = 0; 1511558Srgrimes#ifdef KERBEROS 1521558Srgrimes uid_t last_ruid; 1531558Srgrimes#endif 1541558Srgrimes 1551558Srgrimes#ifdef KERBEROS 1561558Srgrimes last_ruid = -1; 1571558Srgrimes (void)strcpy(realm, KRB_REALM); 1581558Srgrimes#endif 1591558Srgrimes retrycnt = DEF_RETRY; 1601558Srgrimes 1611558Srgrimes mntflags = 0; 1621558Srgrimes nfsargs = nfsdefargs; 1631558Srgrimes nfsargsp = &nfsargs; 1641558Srgrimes while ((c = getopt(argc, argv, 1651558Srgrimes "a:bcdD:g:iKklL:Mm:o:PpqR:r:sTt:w:x:")) != EOF) 1661558Srgrimes switch (c) { 1671558Srgrimes case 'a': 1681558Srgrimes num = strtol(optarg, &p, 10); 1691558Srgrimes if (*p || num < 0) 1701558Srgrimes errx(1, "illegal -a value -- %s", optarg); 1711558Srgrimes nfsargsp->readahead = num; 1721558Srgrimes nfsargsp->flags |= NFSMNT_READAHEAD; 1731558Srgrimes break; 1741558Srgrimes case 'b': 1751558Srgrimes opflags |= BGRND; 1761558Srgrimes break; 1771558Srgrimes case 'c': 1781558Srgrimes nfsargsp->flags |= NFSMNT_NOCONN; 1791558Srgrimes break; 1801558Srgrimes case 'D': 1811558Srgrimes num = strtol(optarg, &p, 10); 1821558Srgrimes if (*p || num <= 0) 1831558Srgrimes errx(1, "illegal -D value -- %s", optarg); 1841558Srgrimes nfsargsp->deadthresh = num; 1851558Srgrimes nfsargsp->flags |= NFSMNT_DEADTHRESH; 1861558Srgrimes break; 1871558Srgrimes case 'd': 1881558Srgrimes nfsargsp->flags |= NFSMNT_DUMBTIMR; 1891558Srgrimes break; 1901558Srgrimes case 'g': 1911558Srgrimes num = strtol(optarg, &p, 10); 1921558Srgrimes if (*p || num <= 0) 1931558Srgrimes errx(1, "illegal -g value -- %s", optarg); 1941558Srgrimes set_rpc_maxgrouplist(num); 1951558Srgrimes nfsargsp->maxgrouplist = num; 1961558Srgrimes nfsargsp->flags |= NFSMNT_MAXGRPS; 1971558Srgrimes break; 1981558Srgrimes case 'i': 1991558Srgrimes nfsargsp->flags |= NFSMNT_INT; 2001558Srgrimes break; 2011558Srgrimes#ifdef KERBEROS 2021558Srgrimes case 'K': 2031558Srgrimes nfsargsp->flags |= NFSMNT_KERB; 2041558Srgrimes break; 2051558Srgrimes#endif 2061558Srgrimes case 'k': 2071558Srgrimes nfsargsp->flags |= NFSMNT_NQLOOKLEASE; 2081558Srgrimes break; 2091558Srgrimes case 'L': 2101558Srgrimes num = strtol(optarg, &p, 10); 2111558Srgrimes if (*p || num < 2) 2121558Srgrimes errx(1, "illegal -L value -- %s", optarg); 2131558Srgrimes nfsargsp->leaseterm = num; 2141558Srgrimes nfsargsp->flags |= NFSMNT_LEASETERM; 2151558Srgrimes break; 2161558Srgrimes case 'l': 2171558Srgrimes nfsargsp->flags |= NFSMNT_RDIRALOOK; 2181558Srgrimes break; 2191558Srgrimes case 'M': 2201558Srgrimes nfsargsp->flags |= NFSMNT_MYWRITE; 2211558Srgrimes break; 2221558Srgrimes#ifdef KERBEROS 2231558Srgrimes case 'm': 2241558Srgrimes (void)strncpy(realm, optarg, REALM_SZ - 1); 2251558Srgrimes realm[REALM_SZ - 1] = '\0'; 2261558Srgrimes break; 2271558Srgrimes#endif 2281558Srgrimes case 'o': 2291558Srgrimes getmntopts(optarg, mopts, &mntflags); 2301558Srgrimes break; 2311558Srgrimes case 'P': 2321558Srgrimes nfsargsp->flags |= NFSMNT_RESVPORT; 2331558Srgrimes break; 2341558Srgrimes#ifdef ISO 2351558Srgrimes case 'p': 2361558Srgrimes nfsargsp->sotype = SOCK_SEQPACKET; 2371558Srgrimes break; 2381558Srgrimes#endif 2391558Srgrimes case 'q': 2401558Srgrimes nfsargsp->flags |= NFSMNT_NQNFS; 2411558Srgrimes break; 2421558Srgrimes case 'R': 2431558Srgrimes num = strtol(optarg, &p, 10); 2441558Srgrimes if (*p || num <= 0) 2451558Srgrimes errx(1, "illegal -R value -- %s", optarg); 2461558Srgrimes retrycnt = num; 2471558Srgrimes break; 2481558Srgrimes case 'r': 2491558Srgrimes num = strtol(optarg, &p, 10); 2501558Srgrimes if (*p || num <= 0) 2511558Srgrimes errx(1, "illegal -r value -- %s", optarg); 2521558Srgrimes nfsargsp->rsize = num; 2531558Srgrimes nfsargsp->flags |= NFSMNT_RSIZE; 2541558Srgrimes break; 2551558Srgrimes case 's': 2561558Srgrimes nfsargsp->flags |= NFSMNT_SOFT; 2571558Srgrimes break; 2581558Srgrimes case 'T': 2591558Srgrimes nfsargsp->sotype = SOCK_STREAM; 2601558Srgrimes break; 2611558Srgrimes case 't': 2621558Srgrimes num = strtol(optarg, &p, 10); 2631558Srgrimes if (*p || num <= 0) 2641558Srgrimes errx(1, "illegal -t value -- %s", optarg); 2651558Srgrimes nfsargsp->timeo = num; 2661558Srgrimes nfsargsp->flags |= NFSMNT_TIMEO; 2671558Srgrimes break; 2681558Srgrimes case 'w': 2691558Srgrimes num = strtol(optarg, &p, 10); 2701558Srgrimes if (*p || num <= 0) 2711558Srgrimes errx(1, "illegal -w value -- %s", optarg); 2721558Srgrimes nfsargsp->wsize = num; 2731558Srgrimes nfsargsp->flags |= NFSMNT_WSIZE; 2741558Srgrimes break; 2751558Srgrimes case 'x': 2761558Srgrimes num = strtol(optarg, &p, 10); 2771558Srgrimes if (*p || num <= 0) 2781558Srgrimes errx(1, "illegal -x value -- %s", optarg); 2791558Srgrimes nfsargsp->retrans = num; 2801558Srgrimes nfsargsp->flags |= NFSMNT_RETRANS; 2811558Srgrimes break; 2821558Srgrimes default: 2831558Srgrimes usage(); 2841558Srgrimes break; 2851558Srgrimes } 2861558Srgrimes argc -= optind; 2871558Srgrimes argv += optind; 2881558Srgrimes 2891558Srgrimes if (argc != 2) 2901558Srgrimes error = 1; 2911558Srgrimes 2921558Srgrimes spec = *argv++; 2931558Srgrimes name = *argv; 2941558Srgrimes 2951558Srgrimes if (!getnfsargs(spec, nfsargsp)) 2961558Srgrimes exit(1); 2971558Srgrimes if (mount(MOUNT_NFS, name, mntflags, nfsargsp)) 2981558Srgrimes err(1, "%s", name); 2991558Srgrimes if (nfsargsp->flags & (NFSMNT_NQNFS | NFSMNT_KERB)) { 3001558Srgrimes if ((opflags & ISBGRND) == 0) { 3011558Srgrimes if (i = fork()) { 3021558Srgrimes if (i == -1) 3031558Srgrimes err(1, "nqnfs 1"); 3041558Srgrimes exit(0); 3051558Srgrimes } 3061558Srgrimes (void) setsid(); 3071558Srgrimes (void) close(STDIN_FILENO); 3081558Srgrimes (void) close(STDOUT_FILENO); 3091558Srgrimes (void) close(STDERR_FILENO); 3101558Srgrimes (void) chdir("/"); 3111558Srgrimes } 3121558Srgrimes openlog("mount_nfs:", LOG_PID, LOG_DAEMON); 3131558Srgrimes nfssvc_flag = NFSSVC_MNTD; 3141558Srgrimes ncd.ncd_dirp = name; 3151558Srgrimes while (nfssvc(nfssvc_flag, (caddr_t)&ncd) < 0) { 3161558Srgrimes if (errno != ENEEDAUTH) { 3171558Srgrimes syslog(LOG_ERR, "nfssvc err %m"); 3181558Srgrimes continue; 3191558Srgrimes } 3201558Srgrimes nfssvc_flag = 3211558Srgrimes NFSSVC_MNTD | NFSSVC_GOTAUTH | NFSSVC_AUTHINFAIL; 3221558Srgrimes#ifdef KERBEROS 3231558Srgrimes /* 3241558Srgrimes * Set up as ncd_authuid for the kerberos call. 3251558Srgrimes * Must set ruid to ncd_authuid and reset the 3261558Srgrimes * ticket name iff ncd_authuid is not the same 3271558Srgrimes * as last time, so that the right ticket file 3281558Srgrimes * is found. 3291558Srgrimes */ 3301558Srgrimes if (ncd.ncd_authuid != last_ruid) { 3311558Srgrimes krb_set_tkt_string(""); 3321558Srgrimes last_ruid = ncd.ncd_authuid; 3331558Srgrimes } 3341558Srgrimes setreuid(ncd.ncd_authuid, 0); 3351558Srgrimes if (krb_mk_req(&kt, "rcmd", inst, realm, 0) == 3361558Srgrimes KSUCCESS && 3371558Srgrimes kt.length <= (RPCAUTH_MAXSIZ - 2 * NFSX_UNSIGNED)) { 3381558Srgrimes ncd.ncd_authtype = RPCAUTH_NQNFS; 3391558Srgrimes ncd.ncd_authlen = kt.length; 3401558Srgrimes ncd.ncd_authstr = (char *)kt.dat; 3411558Srgrimes nfssvc_flag = NFSSVC_MNTD | NFSSVC_GOTAUTH; 3421558Srgrimes } 3431558Srgrimes setreuid(0, 0); 3441558Srgrimes#endif /* KERBEROS */ 3451558Srgrimes } 3461558Srgrimes } 3471558Srgrimes exit(0); 3481558Srgrimes} 3491558Srgrimes 3501558Srgrimesint 3511558Srgrimesgetnfsargs(spec, nfsargsp) 3521558Srgrimes char *spec; 3531558Srgrimes struct nfs_args *nfsargsp; 3541558Srgrimes{ 3551558Srgrimes register CLIENT *clp; 3561558Srgrimes struct hostent *hp; 3571558Srgrimes static struct sockaddr_in saddr; 3581558Srgrimes#ifdef ISO 3591558Srgrimes static struct sockaddr_iso isoaddr; 3601558Srgrimes struct iso_addr *isop; 3611558Srgrimes int isoflag = 0; 3621558Srgrimes#endif 3631558Srgrimes struct timeval pertry, try; 3641558Srgrimes enum clnt_stat clnt_stat; 3651558Srgrimes int so = RPC_ANYSOCK, i; 3661558Srgrimes char *hostp, *delimp; 3671558Srgrimes#ifdef KERBEROS 3681558Srgrimes char *cp; 3691558Srgrimes#endif 3701558Srgrimes u_short tport; 3711558Srgrimes static struct nfhret nfhret; 3721558Srgrimes static char nam[MNAMELEN + 1]; 3731558Srgrimes 3741558Srgrimes strncpy(nam, spec, MNAMELEN); 3751558Srgrimes nam[MNAMELEN] = '\0'; 3761558Srgrimes if ((delimp = strchr(spec, '@')) != NULL) { 3771558Srgrimes hostp = delimp + 1; 3781558Srgrimes } else if ((delimp = strchr(spec, ':')) != NULL) { 3791558Srgrimes hostp = spec; 3801558Srgrimes spec = delimp + 1; 3811558Srgrimes } else { 3821558Srgrimes warnx("no <host>:<dirpath> or <dirpath>@<host> spec"); 3831558Srgrimes return (0); 3841558Srgrimes } 3851558Srgrimes *delimp = '\0'; 3861558Srgrimes /* 3871558Srgrimes * DUMB!! Until the mount protocol works on iso transport, we must 3881558Srgrimes * supply both an iso and an inet address for the host. 3891558Srgrimes */ 3901558Srgrimes#ifdef ISO 3911558Srgrimes if (!strncmp(hostp, "iso=", 4)) { 3921558Srgrimes u_short isoport; 3931558Srgrimes 3941558Srgrimes hostp += 4; 3951558Srgrimes isoflag++; 3961558Srgrimes if ((delimp = strchr(hostp, '+')) == NULL) { 3971558Srgrimes warnx("no iso+inet address"); 3981558Srgrimes return (0); 3991558Srgrimes } 4001558Srgrimes *delimp = '\0'; 4011558Srgrimes if ((isop = iso_addr(hostp)) == NULL) { 4021558Srgrimes warnx("bad ISO address"); 4031558Srgrimes return (0); 4041558Srgrimes } 4051558Srgrimes bzero((caddr_t)&isoaddr, sizeof (isoaddr)); 4061558Srgrimes bcopy((caddr_t)isop, (caddr_t)&isoaddr.siso_addr, 4071558Srgrimes sizeof (struct iso_addr)); 4081558Srgrimes isoaddr.siso_len = sizeof (isoaddr); 4091558Srgrimes isoaddr.siso_family = AF_ISO; 4101558Srgrimes isoaddr.siso_tlen = 2; 4111558Srgrimes isoport = htons(NFS_PORT); 4121558Srgrimes bcopy((caddr_t)&isoport, TSEL(&isoaddr), isoaddr.siso_tlen); 4131558Srgrimes hostp = delimp + 1; 4141558Srgrimes } 4151558Srgrimes#endif /* ISO */ 4161558Srgrimes 4171558Srgrimes /* 4181558Srgrimes * Handle an internet host address and reverse resolve it if 4191558Srgrimes * doing Kerberos. 4201558Srgrimes */ 4211558Srgrimes if (isdigit(*hostp)) { 4221558Srgrimes if ((saddr.sin_addr.s_addr = inet_addr(hostp)) == -1) { 4231558Srgrimes warnx("bad net address %s", hostp); 4241558Srgrimes return (0); 4251558Srgrimes } 4262776Sphk } else if ((hp = gethostbyname(hostp)) != NULL) { 4272776Sphk bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 4282776Sphk } else { 4292776Sphk warnx("can't get net id for host"); 4302776Sphk return (0); 4312776Sphk } 4322776Sphk#ifdef KERBEROS 4332776Sphk if ((nfsargsp->flags & NFSMNT_KERB)) { 4342776Sphk if ((hp = gethostbyaddr((char *)&saddr.sin_addr.s_addr, 4351558Srgrimes sizeof (u_long), AF_INET)) == (struct hostent *)0) { 4361558Srgrimes warnx("can't reverse resolve net address"); 4371558Srgrimes return (0); 4381558Srgrimes } 4392776Sphk bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 4401558Srgrimes strncpy(inst, hp->h_name, INST_SZ); 4411558Srgrimes inst[INST_SZ - 1] = '\0'; 4421558Srgrimes if (cp = strchr(inst, '.')) 4431558Srgrimes *cp = '\0'; 4441558Srgrimes } 4451558Srgrimes#endif /* KERBEROS */ 4461558Srgrimes 4471558Srgrimes nfhret.stat = EACCES; /* Mark not yet successful */ 4481558Srgrimes while (retrycnt > 0) { 4491558Srgrimes saddr.sin_family = AF_INET; 4501558Srgrimes saddr.sin_port = htons(PMAPPORT); 4511558Srgrimes if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 4521558Srgrimes NFS_VER2, IPPROTO_UDP)) == 0) { 4531558Srgrimes if ((opflags & ISBGRND) == 0) 4541558Srgrimes clnt_pcreateerror("NFS Portmap"); 4551558Srgrimes } else { 4561558Srgrimes saddr.sin_port = 0; 4571558Srgrimes pertry.tv_sec = 10; 4581558Srgrimes pertry.tv_usec = 0; 4591558Srgrimes if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 4601558Srgrimes RPCMNT_VER1, pertry, &so)) == NULL) { 4611558Srgrimes if ((opflags & ISBGRND) == 0) 4621558Srgrimes clnt_pcreateerror("Cannot MNT PRC"); 4631558Srgrimes } else { 4641558Srgrimes clp->cl_auth = authunix_create_default(); 4651558Srgrimes try.tv_sec = 10; 4661558Srgrimes try.tv_usec = 0; 4671558Srgrimes clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 4681558Srgrimes xdr_dir, spec, xdr_fh, &nfhret, try); 4691558Srgrimes if (clnt_stat != RPC_SUCCESS) { 4701558Srgrimes if ((opflags & ISBGRND) == 0) 4711558Srgrimes warnx("%s", clnt_sperror(clp, 4721558Srgrimes "bad MNT RPC")); 4731558Srgrimes } else { 4741558Srgrimes auth_destroy(clp->cl_auth); 4751558Srgrimes clnt_destroy(clp); 4761558Srgrimes retrycnt = 0; 4771558Srgrimes } 4781558Srgrimes } 4791558Srgrimes } 4801558Srgrimes if (--retrycnt > 0) { 4811558Srgrimes if (opflags & BGRND) { 4821558Srgrimes opflags &= ~BGRND; 4831558Srgrimes if (i = fork()) { 4841558Srgrimes if (i == -1) 4851558Srgrimes err(1, "nqnfs 2"); 4861558Srgrimes exit(0); 4871558Srgrimes } 4881558Srgrimes (void) setsid(); 4891558Srgrimes (void) close(STDIN_FILENO); 4901558Srgrimes (void) close(STDOUT_FILENO); 4911558Srgrimes (void) close(STDERR_FILENO); 4921558Srgrimes (void) chdir("/"); 4931558Srgrimes opflags |= ISBGRND; 4941558Srgrimes } 4951558Srgrimes sleep(60); 4961558Srgrimes } 4971558Srgrimes } 4981558Srgrimes if (nfhret.stat) { 4991558Srgrimes if (opflags & ISBGRND) 5001558Srgrimes exit(1); 5011558Srgrimes warn("can't access %s", spec); 5021558Srgrimes return (0); 5031558Srgrimes } 5041558Srgrimes saddr.sin_port = htons(tport); 5051558Srgrimes#ifdef ISO 5061558Srgrimes if (isoflag) { 5071558Srgrimes nfsargsp->addr = (struct sockaddr *) &isoaddr; 5081558Srgrimes nfsargsp->addrlen = sizeof (isoaddr); 5091558Srgrimes } else 5101558Srgrimes#endif /* ISO */ 5111558Srgrimes { 5121558Srgrimes nfsargsp->addr = (struct sockaddr *) &saddr; 5131558Srgrimes nfsargsp->addrlen = sizeof (saddr); 5141558Srgrimes } 5151558Srgrimes nfsargsp->fh = &nfhret.nfh; 5161558Srgrimes nfsargsp->hostname = nam; 5171558Srgrimes return (1); 5181558Srgrimes} 5191558Srgrimes 5201558Srgrimes/* 5211558Srgrimes * xdr routines for mount rpc's 5221558Srgrimes */ 5231558Srgrimesint 5241558Srgrimesxdr_dir(xdrsp, dirp) 5251558Srgrimes XDR *xdrsp; 5261558Srgrimes char *dirp; 5271558Srgrimes{ 5281558Srgrimes return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 5291558Srgrimes} 5301558Srgrimes 5311558Srgrimesint 5321558Srgrimesxdr_fh(xdrsp, np) 5331558Srgrimes XDR *xdrsp; 5341558Srgrimes struct nfhret *np; 5351558Srgrimes{ 5361558Srgrimes if (!xdr_u_long(xdrsp, &(np->stat))) 5371558Srgrimes return (0); 5381558Srgrimes if (np->stat) 5391558Srgrimes return (1); 5401558Srgrimes return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 5411558Srgrimes} 5421558Srgrimes 5431558Srgrimes__dead void 5441558Srgrimesusage() 5451558Srgrimes{ 5461558Srgrimes (void)fprintf(stderr, "usage: mount_nfs %s\n%s\n%s\n%s\n", 5471558Srgrimes"[-bcdiKklMPqsT] [-a maxreadahead] [-D deadthresh]", 5481558Srgrimes"\t[-g maxgroups] [-L leaseterm] [-m realm] [-o options] [-R retrycnt]", 5491558Srgrimes"\t[-r readsize] [-t timeout] [-w writesize] [-x retrans]", 5501558Srgrimes"\trhost:path node"); 5511558Srgrimes exit(1); 5521558Srgrimes} 553