mount_nfs.c revision 6043
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 894065Swollman#define ALTF_BG 0x1 904065Swollman#define ALTF_NOCONN 0x2 914065Swollman#define ALTF_DUMBTIMR 0x4 924065Swollman#define ALTF_INTR 0x8 934065Swollman#define ALTF_KERB 0x10 944065Swollman#define ALTF_NQLOOKLSE 0x20 954065Swollman#define ALTF_RDIRALOOK 0x40 964065Swollman#define ALTF_MYWRITE 0x80 974065Swollman#define ALTF_RESVPORT 0x100 984065Swollman#define ALTF_SEQPACKET 0x200 994065Swollman#define ALTF_NQNFS 0x400 1004065Swollman#define ALTF_SOFT 0x800 1014065Swollman#define ALTF_TCP 0x1000 1024065Swollman 1031558Srgrimesstruct mntopt mopts[] = { 1041558Srgrimes MOPT_STDOPTS, 1051558Srgrimes MOPT_FORCE, 1061558Srgrimes MOPT_UPDATE, 1074065Swollman { "bg", 0, ALTF_BG, 1 }, 1084065Swollman { "conn", 1, ALTF_NOCONN, 1 }, 1094065Swollman { "dumbtimer", 0, ALTF_DUMBTIMR, 1 }, 1104065Swollman { "intr", 0, ALTF_INTR, 1 }, 1114065Swollman#ifdef KERBEROS 1124065Swollman { "kerb", 0, ALTF_KERB, 1 }, 1134065Swollman#endif 1144065Swollman { "nqlooklease", 0, ALTF_NQLOOKLSE, 1 }, 1154065Swollman { "rdiralook", 0, ALTF_RDIRALOOK, 1 }, 1164065Swollman { "mywrite", 0, ALTF_MYWRITE, 1 }, 1174065Swollman { "resvport", 0, ALTF_RESVPORT, 1 }, 1184065Swollman#ifdef ISO 1194065Swollman { "seqpacket", 0, ALTF_SEQPACKET, 1 }, 1204065Swollman#endif 1214065Swollman { "nqnfs", 0, ALTF_NQNFS, 1 }, 1224065Swollman { "soft", 0, ALTF_SOFT, 1 }, 1234065Swollman { "tcp", 0, ALTF_TCP, 1 }, 1241558Srgrimes { NULL } 1251558Srgrimes}; 1261558Srgrimes 1271558Srgrimesstruct nfs_args nfsdefargs = { 1281558Srgrimes (struct sockaddr *)0, 1291558Srgrimes sizeof (struct sockaddr_in), 1301558Srgrimes SOCK_DGRAM, 1311558Srgrimes 0, 1321558Srgrimes (nfsv2fh_t *)0, 1331558Srgrimes 0, 1341558Srgrimes NFS_WSIZE, 1351558Srgrimes NFS_RSIZE, 1361558Srgrimes NFS_TIMEO, 1371558Srgrimes NFS_RETRANS, 1381558Srgrimes NFS_MAXGRPS, 1391558Srgrimes NFS_DEFRAHEAD, 1401558Srgrimes NQ_DEFLEASE, 1411558Srgrimes NQ_DEADTHRESH, 1421558Srgrimes (char *)0, 1431558Srgrimes}; 1441558Srgrimes 1451558Srgrimesstruct nfhret { 1461558Srgrimes u_long stat; 1471558Srgrimes nfsv2fh_t nfh; 1481558Srgrimes}; 1491558Srgrimes#define DEF_RETRY 10000 1501558Srgrimes#define BGRND 1 1511558Srgrimes#define ISBGRND 2 1521558Srgrimesint retrycnt = DEF_RETRY; 1531558Srgrimesint opflags = 0; 1541558Srgrimes 1551558Srgrimes#ifdef KERBEROS 1561558Srgrimeschar inst[INST_SZ]; 1571558Srgrimeschar realm[REALM_SZ]; 1581558SrgrimesKTEXT_ST kt; 1591558Srgrimes#endif 1601558Srgrimes 1611558Srgrimesint getnfsargs __P((char *, struct nfs_args *)); 1621558Srgrimes#ifdef ISO 1631558Srgrimesstruct iso_addr *iso_addr __P((const char *)); 1641558Srgrimes#endif 1651558Srgrimesvoid set_rpc_maxgrouplist __P((int)); 1661558Srgrimes__dead void usage __P((void)); 1671558Srgrimesint xdr_dir __P((XDR *, char *)); 1681558Srgrimesint xdr_fh __P((XDR *, struct nfhret *)); 1691558Srgrimes 1701558Srgrimesint 1711558Srgrimesmain(argc, argv) 1721558Srgrimes int argc; 1731558Srgrimes char *argv[]; 1741558Srgrimes{ 1751558Srgrimes register int c; 1761558Srgrimes register struct nfs_args *nfsargsp; 1771558Srgrimes struct nfs_args nfsargs; 1781558Srgrimes struct nfsd_cargs ncd; 1794065Swollman int mntflags, altflags, i, nfssvc_flag, num; 1801558Srgrimes char *name, *p, *spec; 1812999Swollman struct vfsconf *vfc; 1821558Srgrimes#ifdef KERBEROS 1831558Srgrimes uid_t last_ruid; 1841558Srgrimes#endif 1851558Srgrimes 1861558Srgrimes#ifdef KERBEROS 1871558Srgrimes last_ruid = -1; 1881558Srgrimes (void)strcpy(realm, KRB_REALM); 1891558Srgrimes#endif 1901558Srgrimes retrycnt = DEF_RETRY; 1911558Srgrimes 1921558Srgrimes mntflags = 0; 1934065Swollman altflags = 0; 1941558Srgrimes nfsargs = nfsdefargs; 1951558Srgrimes nfsargsp = &nfsargs; 1961558Srgrimes while ((c = getopt(argc, argv, 1971558Srgrimes "a:bcdD:g:iKklL:Mm:o:PpqR:r:sTt:w:x:")) != EOF) 1981558Srgrimes switch (c) { 1991558Srgrimes case 'a': 2001558Srgrimes num = strtol(optarg, &p, 10); 2011558Srgrimes if (*p || num < 0) 2021558Srgrimes errx(1, "illegal -a value -- %s", optarg); 2031558Srgrimes nfsargsp->readahead = num; 2041558Srgrimes nfsargsp->flags |= NFSMNT_READAHEAD; 2051558Srgrimes break; 2061558Srgrimes case 'b': 2071558Srgrimes opflags |= BGRND; 2081558Srgrimes break; 2091558Srgrimes case 'c': 2101558Srgrimes nfsargsp->flags |= NFSMNT_NOCONN; 2111558Srgrimes break; 2121558Srgrimes case 'D': 2131558Srgrimes num = strtol(optarg, &p, 10); 2141558Srgrimes if (*p || num <= 0) 2151558Srgrimes errx(1, "illegal -D value -- %s", optarg); 2161558Srgrimes nfsargsp->deadthresh = num; 2171558Srgrimes nfsargsp->flags |= NFSMNT_DEADTHRESH; 2181558Srgrimes break; 2191558Srgrimes case 'd': 2201558Srgrimes nfsargsp->flags |= NFSMNT_DUMBTIMR; 2211558Srgrimes break; 2221558Srgrimes case 'g': 2231558Srgrimes num = strtol(optarg, &p, 10); 2241558Srgrimes if (*p || num <= 0) 2251558Srgrimes errx(1, "illegal -g value -- %s", optarg); 2261558Srgrimes set_rpc_maxgrouplist(num); 2271558Srgrimes nfsargsp->maxgrouplist = num; 2281558Srgrimes nfsargsp->flags |= NFSMNT_MAXGRPS; 2291558Srgrimes break; 2301558Srgrimes case 'i': 2311558Srgrimes nfsargsp->flags |= NFSMNT_INT; 2321558Srgrimes break; 2331558Srgrimes#ifdef KERBEROS 2341558Srgrimes case 'K': 2351558Srgrimes nfsargsp->flags |= NFSMNT_KERB; 2361558Srgrimes break; 2371558Srgrimes#endif 2381558Srgrimes case 'k': 2391558Srgrimes nfsargsp->flags |= NFSMNT_NQLOOKLEASE; 2401558Srgrimes break; 2411558Srgrimes case 'L': 2421558Srgrimes num = strtol(optarg, &p, 10); 2431558Srgrimes if (*p || num < 2) 2441558Srgrimes errx(1, "illegal -L value -- %s", optarg); 2451558Srgrimes nfsargsp->leaseterm = num; 2461558Srgrimes nfsargsp->flags |= NFSMNT_LEASETERM; 2471558Srgrimes break; 2481558Srgrimes case 'l': 2491558Srgrimes nfsargsp->flags |= NFSMNT_RDIRALOOK; 2501558Srgrimes break; 2511558Srgrimes case 'M': 2521558Srgrimes nfsargsp->flags |= NFSMNT_MYWRITE; 2531558Srgrimes break; 2541558Srgrimes#ifdef KERBEROS 2551558Srgrimes case 'm': 2561558Srgrimes (void)strncpy(realm, optarg, REALM_SZ - 1); 2571558Srgrimes realm[REALM_SZ - 1] = '\0'; 2581558Srgrimes break; 2591558Srgrimes#endif 2601558Srgrimes case 'o': 2614065Swollman getmntopts(optarg, mopts, &mntflags, &altflags); 2624065Swollman if(altflags & ALTF_BG) 2634065Swollman opflags |= BGRND; 2644065Swollman if(altflags & ALTF_NOCONN) 2654065Swollman nfsargsp->flags |= NFSMNT_NOCONN; 2664065Swollman if(altflags & ALTF_DUMBTIMR) 2674065Swollman nfsargsp->flags |= NFSMNT_DUMBTIMR; 2684065Swollman if(altflags & ALTF_INTR) 2694065Swollman nfsargsp->flags |= NFSMNT_INT; 2704065Swollman#ifdef KERBEROS 2714065Swollman if(altflags & ALTF_KERB) 2724065Swollman nfsargsp->flags |= NFSMNT_KERB; 2734065Swollman#endif 2744065Swollman if(altflags & ALTF_NQLOOKLSE) 2754065Swollman nfsargsp->flags |= NFSMNT_NQLOOKLEASE; 2764065Swollman if(altflags & ALTF_RDIRALOOK) 2774065Swollman nfsargsp->flags |= NFSMNT_RDIRALOOK; 2784065Swollman if(altflags & ALTF_MYWRITE) 2794065Swollman nfsargsp->flags |= NFSMNT_MYWRITE; 2804065Swollman if(altflags & ALTF_RESVPORT) 2814065Swollman nfsargsp->flags |= NFSMNT_RESVPORT; 2824065Swollman#ifdef ISO 2834065Swollman if(altflags & ALTF_SEQPACKET) 2844065Swollman nfsargsp->sotype = SOCK_SEQPACKET; 2854065Swollman#endif 2864065Swollman if(altflags & ALTF_NQNFS) 2874065Swollman nfsargsp->flags |= NFSMNT_NQNFS; 2884065Swollman if(altflags & ALTF_SOFT) 2894065Swollman nfsargsp->flags |= NFSMNT_SOFT; 2904065Swollman if(altflags & ALTF_TCP) 2914065Swollman nfsargsp->sotype = SOCK_STREAM; 2924065Swollman altflags = 0; 2931558Srgrimes break; 2941558Srgrimes case 'P': 2951558Srgrimes nfsargsp->flags |= NFSMNT_RESVPORT; 2961558Srgrimes break; 2971558Srgrimes#ifdef ISO 2981558Srgrimes case 'p': 2991558Srgrimes nfsargsp->sotype = SOCK_SEQPACKET; 3001558Srgrimes break; 3011558Srgrimes#endif 3021558Srgrimes case 'q': 3031558Srgrimes nfsargsp->flags |= NFSMNT_NQNFS; 3041558Srgrimes break; 3051558Srgrimes case 'R': 3061558Srgrimes num = strtol(optarg, &p, 10); 3071558Srgrimes if (*p || num <= 0) 3081558Srgrimes errx(1, "illegal -R value -- %s", optarg); 3091558Srgrimes retrycnt = num; 3101558Srgrimes break; 3111558Srgrimes case 'r': 3121558Srgrimes num = strtol(optarg, &p, 10); 3131558Srgrimes if (*p || num <= 0) 3141558Srgrimes errx(1, "illegal -r value -- %s", optarg); 3151558Srgrimes nfsargsp->rsize = num; 3161558Srgrimes nfsargsp->flags |= NFSMNT_RSIZE; 3171558Srgrimes break; 3181558Srgrimes case 's': 3191558Srgrimes nfsargsp->flags |= NFSMNT_SOFT; 3201558Srgrimes break; 3211558Srgrimes case 'T': 3221558Srgrimes nfsargsp->sotype = SOCK_STREAM; 3231558Srgrimes break; 3241558Srgrimes case 't': 3251558Srgrimes num = strtol(optarg, &p, 10); 3261558Srgrimes if (*p || num <= 0) 3271558Srgrimes errx(1, "illegal -t value -- %s", optarg); 3281558Srgrimes nfsargsp->timeo = num; 3291558Srgrimes nfsargsp->flags |= NFSMNT_TIMEO; 3301558Srgrimes break; 3311558Srgrimes case 'w': 3321558Srgrimes num = strtol(optarg, &p, 10); 3331558Srgrimes if (*p || num <= 0) 3341558Srgrimes errx(1, "illegal -w value -- %s", optarg); 3351558Srgrimes nfsargsp->wsize = num; 3361558Srgrimes nfsargsp->flags |= NFSMNT_WSIZE; 3371558Srgrimes break; 3381558Srgrimes case 'x': 3391558Srgrimes num = strtol(optarg, &p, 10); 3401558Srgrimes if (*p || num <= 0) 3411558Srgrimes errx(1, "illegal -x value -- %s", optarg); 3421558Srgrimes nfsargsp->retrans = num; 3431558Srgrimes nfsargsp->flags |= NFSMNT_RETRANS; 3441558Srgrimes break; 3451558Srgrimes default: 3461558Srgrimes usage(); 3471558Srgrimes break; 3481558Srgrimes } 3491558Srgrimes argc -= optind; 3501558Srgrimes argv += optind; 3511558Srgrimes 3521558Srgrimes if (argc != 2) 3535966Sdg usage(); 3541558Srgrimes 3551558Srgrimes spec = *argv++; 3561558Srgrimes name = *argv; 3571558Srgrimes 3581558Srgrimes if (!getnfsargs(spec, nfsargsp)) 3591558Srgrimes exit(1); 3602999Swollman 3612999Swollman vfc = getvfsbyname("nfs"); 3622999Swollman if(!vfc && vfsisloadable("nfs")) { 3632999Swollman if(vfsload("nfs")) 3642999Swollman err(1, "vfsload(nfs)"); 3652999Swollman endvfsent(); /* flush cache */ 3662999Swollman vfc = getvfsbyname("nfs"); 3672999Swollman } 3682999Swollman 3692999Swollman if (mount(vfc ? vfc->vfc_index : MOUNT_NFS, name, mntflags, nfsargsp)) 3701558Srgrimes err(1, "%s", name); 3711558Srgrimes if (nfsargsp->flags & (NFSMNT_NQNFS | NFSMNT_KERB)) { 3721558Srgrimes if ((opflags & ISBGRND) == 0) { 3731558Srgrimes if (i = fork()) { 3741558Srgrimes if (i == -1) 3751558Srgrimes err(1, "nqnfs 1"); 3761558Srgrimes exit(0); 3771558Srgrimes } 3781558Srgrimes (void) setsid(); 3791558Srgrimes (void) close(STDIN_FILENO); 3801558Srgrimes (void) close(STDOUT_FILENO); 3811558Srgrimes (void) close(STDERR_FILENO); 3821558Srgrimes (void) chdir("/"); 3831558Srgrimes } 3841558Srgrimes openlog("mount_nfs:", LOG_PID, LOG_DAEMON); 3851558Srgrimes nfssvc_flag = NFSSVC_MNTD; 3861558Srgrimes ncd.ncd_dirp = name; 3871558Srgrimes while (nfssvc(nfssvc_flag, (caddr_t)&ncd) < 0) { 3881558Srgrimes if (errno != ENEEDAUTH) { 3891558Srgrimes syslog(LOG_ERR, "nfssvc err %m"); 3901558Srgrimes continue; 3911558Srgrimes } 3921558Srgrimes nfssvc_flag = 3931558Srgrimes NFSSVC_MNTD | NFSSVC_GOTAUTH | NFSSVC_AUTHINFAIL; 3941558Srgrimes#ifdef KERBEROS 3951558Srgrimes /* 3961558Srgrimes * Set up as ncd_authuid for the kerberos call. 3971558Srgrimes * Must set ruid to ncd_authuid and reset the 3981558Srgrimes * ticket name iff ncd_authuid is not the same 3991558Srgrimes * as last time, so that the right ticket file 4001558Srgrimes * is found. 4011558Srgrimes */ 4021558Srgrimes if (ncd.ncd_authuid != last_ruid) { 4036043Sdfr char buf[512]; 4046043Sdfr (void)sprintf(buf, "%s%d", 4056043Sdfr TKT_ROOT, ncd.ncd_authuid); 4066043Sdfr krb_set_tkt_string(buf); 4071558Srgrimes last_ruid = ncd.ncd_authuid; 4081558Srgrimes } 4091558Srgrimes if (krb_mk_req(&kt, "rcmd", inst, realm, 0) == 4101558Srgrimes KSUCCESS && 4111558Srgrimes kt.length <= (RPCAUTH_MAXSIZ - 2 * NFSX_UNSIGNED)) { 4121558Srgrimes ncd.ncd_authtype = RPCAUTH_NQNFS; 4131558Srgrimes ncd.ncd_authlen = kt.length; 4141558Srgrimes ncd.ncd_authstr = (char *)kt.dat; 4151558Srgrimes nfssvc_flag = NFSSVC_MNTD | NFSSVC_GOTAUTH; 4161558Srgrimes } 4171558Srgrimes#endif /* KERBEROS */ 4181558Srgrimes } 4191558Srgrimes } 4201558Srgrimes exit(0); 4211558Srgrimes} 4221558Srgrimes 4231558Srgrimesint 4241558Srgrimesgetnfsargs(spec, nfsargsp) 4251558Srgrimes char *spec; 4261558Srgrimes struct nfs_args *nfsargsp; 4271558Srgrimes{ 4281558Srgrimes register CLIENT *clp; 4291558Srgrimes struct hostent *hp; 4301558Srgrimes static struct sockaddr_in saddr; 4311558Srgrimes#ifdef ISO 4321558Srgrimes static struct sockaddr_iso isoaddr; 4331558Srgrimes struct iso_addr *isop; 4341558Srgrimes int isoflag = 0; 4351558Srgrimes#endif 4361558Srgrimes struct timeval pertry, try; 4371558Srgrimes enum clnt_stat clnt_stat; 4381558Srgrimes int so = RPC_ANYSOCK, i; 4391558Srgrimes char *hostp, *delimp; 4401558Srgrimes#ifdef KERBEROS 4411558Srgrimes char *cp; 4421558Srgrimes#endif 4431558Srgrimes u_short tport; 4441558Srgrimes static struct nfhret nfhret; 4451558Srgrimes static char nam[MNAMELEN + 1]; 4461558Srgrimes 4471558Srgrimes strncpy(nam, spec, MNAMELEN); 4481558Srgrimes nam[MNAMELEN] = '\0'; 4491558Srgrimes if ((delimp = strchr(spec, '@')) != NULL) { 4501558Srgrimes hostp = delimp + 1; 4511558Srgrimes } else if ((delimp = strchr(spec, ':')) != NULL) { 4521558Srgrimes hostp = spec; 4531558Srgrimes spec = delimp + 1; 4541558Srgrimes } else { 4551558Srgrimes warnx("no <host>:<dirpath> or <dirpath>@<host> spec"); 4561558Srgrimes return (0); 4571558Srgrimes } 4581558Srgrimes *delimp = '\0'; 4591558Srgrimes /* 4601558Srgrimes * DUMB!! Until the mount protocol works on iso transport, we must 4611558Srgrimes * supply both an iso and an inet address for the host. 4621558Srgrimes */ 4631558Srgrimes#ifdef ISO 4641558Srgrimes if (!strncmp(hostp, "iso=", 4)) { 4651558Srgrimes u_short isoport; 4661558Srgrimes 4671558Srgrimes hostp += 4; 4681558Srgrimes isoflag++; 4691558Srgrimes if ((delimp = strchr(hostp, '+')) == NULL) { 4701558Srgrimes warnx("no iso+inet address"); 4711558Srgrimes return (0); 4721558Srgrimes } 4731558Srgrimes *delimp = '\0'; 4741558Srgrimes if ((isop = iso_addr(hostp)) == NULL) { 4751558Srgrimes warnx("bad ISO address"); 4761558Srgrimes return (0); 4771558Srgrimes } 4781558Srgrimes bzero((caddr_t)&isoaddr, sizeof (isoaddr)); 4791558Srgrimes bcopy((caddr_t)isop, (caddr_t)&isoaddr.siso_addr, 4801558Srgrimes sizeof (struct iso_addr)); 4811558Srgrimes isoaddr.siso_len = sizeof (isoaddr); 4821558Srgrimes isoaddr.siso_family = AF_ISO; 4831558Srgrimes isoaddr.siso_tlen = 2; 4841558Srgrimes isoport = htons(NFS_PORT); 4851558Srgrimes bcopy((caddr_t)&isoport, TSEL(&isoaddr), isoaddr.siso_tlen); 4861558Srgrimes hostp = delimp + 1; 4871558Srgrimes } 4881558Srgrimes#endif /* ISO */ 4891558Srgrimes 4901558Srgrimes /* 4911558Srgrimes * Handle an internet host address and reverse resolve it if 4921558Srgrimes * doing Kerberos. 4931558Srgrimes */ 4941558Srgrimes if (isdigit(*hostp)) { 4951558Srgrimes if ((saddr.sin_addr.s_addr = inet_addr(hostp)) == -1) { 4961558Srgrimes warnx("bad net address %s", hostp); 4971558Srgrimes return (0); 4981558Srgrimes } 4992776Sphk } else if ((hp = gethostbyname(hostp)) != NULL) { 5002776Sphk bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 5012776Sphk } else { 5022776Sphk warnx("can't get net id for host"); 5032776Sphk return (0); 5042776Sphk } 5052776Sphk#ifdef KERBEROS 5062776Sphk if ((nfsargsp->flags & NFSMNT_KERB)) { 5072776Sphk if ((hp = gethostbyaddr((char *)&saddr.sin_addr.s_addr, 5081558Srgrimes sizeof (u_long), AF_INET)) == (struct hostent *)0) { 5091558Srgrimes warnx("can't reverse resolve net address"); 5101558Srgrimes return (0); 5111558Srgrimes } 5122776Sphk bcopy(hp->h_addr, (caddr_t)&saddr.sin_addr, hp->h_length); 5131558Srgrimes strncpy(inst, hp->h_name, INST_SZ); 5141558Srgrimes inst[INST_SZ - 1] = '\0'; 5151558Srgrimes if (cp = strchr(inst, '.')) 5161558Srgrimes *cp = '\0'; 5171558Srgrimes } 5181558Srgrimes#endif /* KERBEROS */ 5191558Srgrimes 5201558Srgrimes nfhret.stat = EACCES; /* Mark not yet successful */ 5211558Srgrimes while (retrycnt > 0) { 5221558Srgrimes saddr.sin_family = AF_INET; 5231558Srgrimes saddr.sin_port = htons(PMAPPORT); 5241558Srgrimes if ((tport = pmap_getport(&saddr, RPCPROG_NFS, 5251558Srgrimes NFS_VER2, IPPROTO_UDP)) == 0) { 5261558Srgrimes if ((opflags & ISBGRND) == 0) 5271558Srgrimes clnt_pcreateerror("NFS Portmap"); 5281558Srgrimes } else { 5291558Srgrimes saddr.sin_port = 0; 5301558Srgrimes pertry.tv_sec = 10; 5311558Srgrimes pertry.tv_usec = 0; 5321558Srgrimes if ((clp = clntudp_create(&saddr, RPCPROG_MNT, 5331558Srgrimes RPCMNT_VER1, pertry, &so)) == NULL) { 5341558Srgrimes if ((opflags & ISBGRND) == 0) 5354822Sats clnt_pcreateerror("Cannot MNT RPC"); 5361558Srgrimes } else { 5371558Srgrimes clp->cl_auth = authunix_create_default(); 5381558Srgrimes try.tv_sec = 10; 5391558Srgrimes try.tv_usec = 0; 5401558Srgrimes clnt_stat = clnt_call(clp, RPCMNT_MOUNT, 5411558Srgrimes xdr_dir, spec, xdr_fh, &nfhret, try); 5421558Srgrimes if (clnt_stat != RPC_SUCCESS) { 5431558Srgrimes if ((opflags & ISBGRND) == 0) 5441558Srgrimes warnx("%s", clnt_sperror(clp, 5451558Srgrimes "bad MNT RPC")); 5461558Srgrimes } else { 5471558Srgrimes auth_destroy(clp->cl_auth); 5481558Srgrimes clnt_destroy(clp); 5491558Srgrimes retrycnt = 0; 5501558Srgrimes } 5511558Srgrimes } 5521558Srgrimes } 5531558Srgrimes if (--retrycnt > 0) { 5541558Srgrimes if (opflags & BGRND) { 5551558Srgrimes opflags &= ~BGRND; 5561558Srgrimes if (i = fork()) { 5571558Srgrimes if (i == -1) 5581558Srgrimes err(1, "nqnfs 2"); 5591558Srgrimes exit(0); 5601558Srgrimes } 5611558Srgrimes (void) setsid(); 5621558Srgrimes (void) close(STDIN_FILENO); 5631558Srgrimes (void) close(STDOUT_FILENO); 5641558Srgrimes (void) close(STDERR_FILENO); 5651558Srgrimes (void) chdir("/"); 5661558Srgrimes opflags |= ISBGRND; 5671558Srgrimes } 5681558Srgrimes sleep(60); 5691558Srgrimes } 5701558Srgrimes } 5711558Srgrimes if (nfhret.stat) { 5721558Srgrimes if (opflags & ISBGRND) 5731558Srgrimes exit(1); 5745966Sdg errno = nfhret.stat; 5751558Srgrimes warn("can't access %s", spec); 5761558Srgrimes return (0); 5771558Srgrimes } 5781558Srgrimes saddr.sin_port = htons(tport); 5791558Srgrimes#ifdef ISO 5801558Srgrimes if (isoflag) { 5811558Srgrimes nfsargsp->addr = (struct sockaddr *) &isoaddr; 5821558Srgrimes nfsargsp->addrlen = sizeof (isoaddr); 5831558Srgrimes } else 5841558Srgrimes#endif /* ISO */ 5851558Srgrimes { 5861558Srgrimes nfsargsp->addr = (struct sockaddr *) &saddr; 5871558Srgrimes nfsargsp->addrlen = sizeof (saddr); 5881558Srgrimes } 5891558Srgrimes nfsargsp->fh = &nfhret.nfh; 5901558Srgrimes nfsargsp->hostname = nam; 5911558Srgrimes return (1); 5921558Srgrimes} 5931558Srgrimes 5941558Srgrimes/* 5951558Srgrimes * xdr routines for mount rpc's 5961558Srgrimes */ 5971558Srgrimesint 5981558Srgrimesxdr_dir(xdrsp, dirp) 5991558Srgrimes XDR *xdrsp; 6001558Srgrimes char *dirp; 6011558Srgrimes{ 6021558Srgrimes return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN)); 6031558Srgrimes} 6041558Srgrimes 6051558Srgrimesint 6061558Srgrimesxdr_fh(xdrsp, np) 6071558Srgrimes XDR *xdrsp; 6081558Srgrimes struct nfhret *np; 6091558Srgrimes{ 6101558Srgrimes if (!xdr_u_long(xdrsp, &(np->stat))) 6111558Srgrimes return (0); 6121558Srgrimes if (np->stat) 6131558Srgrimes return (1); 6141558Srgrimes return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH)); 6151558Srgrimes} 6161558Srgrimes 6171558Srgrimes__dead void 6181558Srgrimesusage() 6191558Srgrimes{ 6201558Srgrimes (void)fprintf(stderr, "usage: mount_nfs %s\n%s\n%s\n%s\n", 6211558Srgrimes"[-bcdiKklMPqsT] [-a maxreadahead] [-D deadthresh]", 6221558Srgrimes"\t[-g maxgroups] [-L leaseterm] [-m realm] [-o options] [-R retrycnt]", 6231558Srgrimes"\t[-r readsize] [-t timeout] [-w writesize] [-x retrans]", 6241558Srgrimes"\trhost:path node"); 6251558Srgrimes exit(1); 6261558Srgrimes} 627