Home | History | Annotate | Line # | Download | only in mount_nfs
mount_nfs.c revision 1.10
      1  1.10  mycroft /*	$NetBSD: mount_nfs.c,v 1.10 1995/05/21 15:17:13 mycroft Exp $	*/
      2   1.8      cgd 
      3   1.1  mycroft /*
      4   1.1  mycroft  * Copyright (c) 1992, 1993, 1994
      5   1.1  mycroft  *	The Regents of the University of California.  All rights reserved.
      6   1.1  mycroft  *
      7   1.1  mycroft  * This code is derived from software contributed to Berkeley by
      8   1.1  mycroft  * Rick Macklem at The University of Guelph.
      9   1.1  mycroft  *
     10   1.1  mycroft  * Redistribution and use in source and binary forms, with or without
     11   1.1  mycroft  * modification, are permitted provided that the following conditions
     12   1.1  mycroft  * are met:
     13   1.1  mycroft  * 1. Redistributions of source code must retain the above copyright
     14   1.1  mycroft  *    notice, this list of conditions and the following disclaimer.
     15   1.1  mycroft  * 2. Redistributions in binary form must reproduce the above copyright
     16   1.1  mycroft  *    notice, this list of conditions and the following disclaimer in the
     17   1.1  mycroft  *    documentation and/or other materials provided with the distribution.
     18   1.1  mycroft  * 3. All advertising materials mentioning features or use of this software
     19   1.1  mycroft  *    must display the following acknowledgement:
     20   1.1  mycroft  *	This product includes software developed by the University of
     21   1.1  mycroft  *	California, Berkeley and its contributors.
     22   1.1  mycroft  * 4. Neither the name of the University nor the names of its contributors
     23   1.1  mycroft  *    may be used to endorse or promote products derived from this software
     24   1.1  mycroft  *    without specific prior written permission.
     25   1.1  mycroft  *
     26   1.1  mycroft  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     27   1.1  mycroft  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     28   1.1  mycroft  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29   1.1  mycroft  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     30   1.1  mycroft  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     31   1.1  mycroft  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     32   1.1  mycroft  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     33   1.1  mycroft  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34   1.1  mycroft  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     35   1.1  mycroft  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     36   1.1  mycroft  * SUCH DAMAGE.
     37   1.1  mycroft  */
     38   1.1  mycroft 
     39   1.1  mycroft #ifndef lint
     40   1.1  mycroft static char copyright[] =
     41   1.1  mycroft "@(#) Copyright (c) 1992, 1993, 1994\n\
     42   1.1  mycroft 	The Regents of the University of California.  All rights reserved.\n";
     43   1.1  mycroft #endif /* not lint */
     44   1.1  mycroft 
     45   1.1  mycroft #ifndef lint
     46   1.8      cgd #if 0
     47   1.8      cgd static char sccsid[] = "@(#)mount_nfs.c	8.3 (Berkeley) 3/27/94";
     48   1.8      cgd #else
     49  1.10  mycroft static char rcsid[] = "$NetBSD: mount_nfs.c,v 1.10 1995/05/21 15:17:13 mycroft Exp $";
     50   1.8      cgd #endif
     51   1.1  mycroft #endif /* not lint */
     52   1.1  mycroft 
     53   1.1  mycroft #include <sys/param.h>
     54   1.1  mycroft #include <sys/mount.h>
     55   1.1  mycroft #include <sys/socket.h>
     56   1.1  mycroft #include <sys/socketvar.h>
     57   1.1  mycroft #include <sys/stat.h>
     58   1.9      jtc #include <syslog.h>
     59   1.1  mycroft 
     60   1.1  mycroft #include <rpc/rpc.h>
     61   1.1  mycroft #include <rpc/pmap_clnt.h>
     62   1.1  mycroft #include <rpc/pmap_prot.h>
     63   1.1  mycroft 
     64   1.1  mycroft #ifdef ISO
     65   1.1  mycroft #include <netiso/iso.h>
     66   1.1  mycroft #endif
     67   1.1  mycroft 
     68   1.1  mycroft #ifdef KERBEROS
     69   1.1  mycroft #include <kerberosIV/des.h>
     70   1.1  mycroft #include <kerberosIV/krb.h>
     71   1.1  mycroft #endif
     72   1.1  mycroft 
     73   1.1  mycroft #include <nfs/rpcv2.h>
     74   1.1  mycroft #include <nfs/nfsv2.h>
     75   1.9      jtc #define _KERNEL
     76   1.1  mycroft #include <nfs/nfs.h>
     77   1.9      jtc #undef _KERNEL
     78   1.1  mycroft #include <nfs/nqnfs.h>
     79   1.1  mycroft 
     80   1.1  mycroft #include <arpa/inet.h>
     81   1.1  mycroft 
     82   1.1  mycroft #include <ctype.h>
     83   1.1  mycroft #include <err.h>
     84   1.1  mycroft #include <errno.h>
     85   1.1  mycroft #include <fcntl.h>
     86   1.1  mycroft #include <netdb.h>
     87   1.1  mycroft #include <signal.h>
     88   1.1  mycroft #include <stdio.h>
     89   1.1  mycroft #include <stdlib.h>
     90   1.1  mycroft #include <strings.h>
     91   1.1  mycroft #include <unistd.h>
     92   1.1  mycroft 
     93   1.1  mycroft #include "mntopts.h"
     94   1.1  mycroft 
     95   1.1  mycroft struct mntopt mopts[] = {
     96   1.1  mycroft 	MOPT_STDOPTS,
     97   1.1  mycroft 	MOPT_FORCE,
     98   1.1  mycroft 	MOPT_UPDATE,
     99   1.1  mycroft 	{ NULL }
    100   1.1  mycroft };
    101   1.1  mycroft 
    102   1.1  mycroft struct nfs_args nfsdefargs = {
    103   1.1  mycroft 	(struct sockaddr *)0,
    104   1.1  mycroft 	sizeof (struct sockaddr_in),
    105   1.1  mycroft 	SOCK_DGRAM,
    106   1.1  mycroft 	0,
    107   1.1  mycroft 	(nfsv2fh_t *)0,
    108   1.1  mycroft 	0,
    109   1.1  mycroft 	NFS_WSIZE,
    110   1.1  mycroft 	NFS_RSIZE,
    111   1.1  mycroft 	NFS_TIMEO,
    112   1.1  mycroft 	NFS_RETRANS,
    113   1.1  mycroft 	NFS_MAXGRPS,
    114   1.1  mycroft 	NFS_DEFRAHEAD,
    115   1.1  mycroft 	NQ_DEFLEASE,
    116   1.1  mycroft 	NQ_DEADTHRESH,
    117   1.1  mycroft 	(char *)0,
    118   1.1  mycroft };
    119   1.1  mycroft 
    120   1.1  mycroft struct nfhret {
    121   1.1  mycroft 	u_long	stat;
    122   1.1  mycroft 	nfsv2fh_t nfh;
    123   1.1  mycroft };
    124   1.1  mycroft #define	DEF_RETRY	10000
    125   1.1  mycroft #define	BGRND	1
    126   1.1  mycroft #define	ISBGRND	2
    127   1.1  mycroft int retrycnt = DEF_RETRY;
    128   1.1  mycroft int opflags = 0;
    129   1.1  mycroft 
    130   1.1  mycroft #ifdef KERBEROS
    131   1.1  mycroft char inst[INST_SZ];
    132   1.1  mycroft char realm[REALM_SZ];
    133   1.1  mycroft KTEXT_ST kt;
    134   1.1  mycroft #endif
    135   1.1  mycroft 
    136   1.1  mycroft int	getnfsargs __P((char *, struct nfs_args *));
    137   1.1  mycroft #ifdef ISO
    138   1.1  mycroft struct	iso_addr *iso_addr __P((const char *));
    139   1.1  mycroft #endif
    140   1.1  mycroft void	set_rpc_maxgrouplist __P((int));
    141   1.1  mycroft __dead	void usage __P((void));
    142   1.1  mycroft int	xdr_dir __P((XDR *, char *));
    143   1.1  mycroft int	xdr_fh __P((XDR *, struct nfhret *));
    144   1.1  mycroft 
    145   1.1  mycroft int
    146   1.1  mycroft main(argc, argv)
    147   1.1  mycroft 	int argc;
    148   1.1  mycroft 	char *argv[];
    149   1.1  mycroft {
    150   1.1  mycroft 	register int c;
    151   1.1  mycroft 	register struct nfs_args *nfsargsp;
    152   1.1  mycroft 	struct nfs_args nfsargs;
    153   1.1  mycroft 	struct nfsd_cargs ncd;
    154   1.1  mycroft 	int mntflags, i, nfssvc_flag, num;
    155   1.1  mycroft 	char *name, *p, *spec;
    156   1.1  mycroft 	int error = 0;
    157   1.1  mycroft #ifdef KERBEROS
    158   1.1  mycroft 	uid_t last_ruid;
    159   1.1  mycroft #endif
    160   1.1  mycroft 
    161   1.1  mycroft #ifdef KERBEROS
    162   1.1  mycroft 	last_ruid = -1;
    163   1.3   brezak 	if (krb_get_lrealm(realm, 0) != KSUCCESS)
    164   1.3   brezak 	    (void)strcpy(realm, KRB_REALM);
    165   1.1  mycroft #endif
    166   1.1  mycroft 	retrycnt = DEF_RETRY;
    167   1.1  mycroft 
    168   1.1  mycroft 	mntflags = 0;
    169   1.1  mycroft 	nfsargs = nfsdefargs;
    170   1.1  mycroft 	nfsargsp = &nfsargs;
    171   1.1  mycroft 	while ((c = getopt(argc, argv,
    172   1.1  mycroft 	    "a:bcdD:g:iKklL:Mm:o:PpqR:r:sTt:w:x:")) != EOF)
    173   1.1  mycroft 		switch (c) {
    174   1.1  mycroft 		case 'a':
    175   1.1  mycroft 			num = strtol(optarg, &p, 10);
    176   1.1  mycroft 			if (*p || num < 0)
    177   1.1  mycroft 				errx(1, "illegal -a value -- %s", optarg);
    178   1.1  mycroft 			nfsargsp->readahead = num;
    179   1.1  mycroft 			nfsargsp->flags |= NFSMNT_READAHEAD;
    180   1.1  mycroft 			break;
    181   1.1  mycroft 		case 'b':
    182   1.1  mycroft 			opflags |= BGRND;
    183   1.1  mycroft 			break;
    184   1.1  mycroft 		case 'c':
    185   1.1  mycroft 			nfsargsp->flags |= NFSMNT_NOCONN;
    186   1.1  mycroft 			break;
    187   1.1  mycroft 		case 'D':
    188   1.1  mycroft 			num = strtol(optarg, &p, 10);
    189   1.1  mycroft 			if (*p || num <= 0)
    190   1.1  mycroft 				errx(1, "illegal -D value -- %s", optarg);
    191   1.1  mycroft 			nfsargsp->deadthresh = num;
    192   1.1  mycroft 			nfsargsp->flags |= NFSMNT_DEADTHRESH;
    193   1.1  mycroft 			break;
    194   1.1  mycroft 		case 'd':
    195   1.1  mycroft 			nfsargsp->flags |= NFSMNT_DUMBTIMR;
    196   1.1  mycroft 			break;
    197   1.1  mycroft #if 0 /* XXXX */
    198   1.1  mycroft 		case 'g':
    199   1.1  mycroft 			num = strtol(optarg, &p, 10);
    200   1.1  mycroft 			if (*p || num <= 0)
    201   1.1  mycroft 				errx(1, "illegal -g value -- %s", optarg);
    202   1.1  mycroft 			set_rpc_maxgrouplist(num);
    203   1.1  mycroft 			nfsargsp->maxgrouplist = num;
    204   1.1  mycroft 			nfsargsp->flags |= NFSMNT_MAXGRPS;
    205   1.1  mycroft 			break;
    206   1.1  mycroft #endif
    207   1.1  mycroft 		case 'i':
    208   1.1  mycroft 			nfsargsp->flags |= NFSMNT_INT;
    209   1.1  mycroft 			break;
    210   1.1  mycroft #ifdef KERBEROS
    211   1.1  mycroft 		case 'K':
    212   1.1  mycroft 			nfsargsp->flags |= NFSMNT_KERB;
    213   1.1  mycroft 			break;
    214   1.1  mycroft #endif
    215   1.1  mycroft 		case 'k':
    216   1.1  mycroft 			nfsargsp->flags |= NFSMNT_NQLOOKLEASE;
    217   1.1  mycroft 			break;
    218   1.1  mycroft 		case 'L':
    219   1.1  mycroft 			num = strtol(optarg, &p, 10);
    220   1.1  mycroft 			if (*p || num < 2)
    221   1.1  mycroft 				errx(1, "illegal -L value -- %s", optarg);
    222   1.1  mycroft 			nfsargsp->leaseterm = num;
    223   1.1  mycroft 			nfsargsp->flags |= NFSMNT_LEASETERM;
    224   1.1  mycroft 			break;
    225   1.1  mycroft 		case 'l':
    226   1.1  mycroft 			nfsargsp->flags |= NFSMNT_RDIRALOOK;
    227   1.1  mycroft 			break;
    228   1.1  mycroft 		case 'M':
    229   1.1  mycroft 			nfsargsp->flags |= NFSMNT_MYWRITE;
    230   1.1  mycroft 			break;
    231   1.1  mycroft #ifdef KERBEROS
    232   1.1  mycroft 		case 'm':
    233   1.1  mycroft 			(void)strncpy(realm, optarg, REALM_SZ - 1);
    234   1.1  mycroft 			realm[REALM_SZ - 1] = '\0';
    235   1.1  mycroft 			break;
    236   1.1  mycroft #endif
    237   1.1  mycroft 		case 'o':
    238   1.1  mycroft 			getmntopts(optarg, mopts, &mntflags);
    239   1.1  mycroft 			break;
    240   1.1  mycroft 		case 'P':
    241   1.1  mycroft 			nfsargsp->flags |= NFSMNT_RESVPORT;
    242   1.1  mycroft 			break;
    243   1.1  mycroft #ifdef ISO
    244   1.1  mycroft 		case 'p':
    245   1.1  mycroft 			nfsargsp->sotype = SOCK_SEQPACKET;
    246   1.1  mycroft 			break;
    247   1.1  mycroft #endif
    248   1.1  mycroft 		case 'q':
    249   1.1  mycroft 			nfsargsp->flags |= NFSMNT_NQNFS;
    250   1.1  mycroft 			break;
    251   1.1  mycroft 		case 'R':
    252   1.1  mycroft 			num = strtol(optarg, &p, 10);
    253   1.1  mycroft 			if (*p || num <= 0)
    254   1.1  mycroft 				errx(1, "illegal -R value -- %s", optarg);
    255   1.1  mycroft 			retrycnt = num;
    256   1.1  mycroft 			break;
    257   1.1  mycroft 		case 'r':
    258   1.1  mycroft 			num = strtol(optarg, &p, 10);
    259   1.1  mycroft 			if (*p || num <= 0)
    260   1.1  mycroft 				errx(1, "illegal -r value -- %s", optarg);
    261   1.1  mycroft 			nfsargsp->rsize = num;
    262   1.1  mycroft 			nfsargsp->flags |= NFSMNT_RSIZE;
    263   1.1  mycroft 			break;
    264   1.1  mycroft 		case 's':
    265   1.1  mycroft 			nfsargsp->flags |= NFSMNT_SOFT;
    266   1.1  mycroft 			break;
    267   1.1  mycroft 		case 'T':
    268   1.1  mycroft 			nfsargsp->sotype = SOCK_STREAM;
    269   1.1  mycroft 			break;
    270   1.1  mycroft 		case 't':
    271   1.1  mycroft 			num = strtol(optarg, &p, 10);
    272   1.1  mycroft 			if (*p || num <= 0)
    273   1.1  mycroft 				errx(1, "illegal -t value -- %s", optarg);
    274   1.1  mycroft 			nfsargsp->timeo = num;
    275   1.1  mycroft 			nfsargsp->flags |= NFSMNT_TIMEO;
    276   1.1  mycroft 			break;
    277   1.1  mycroft 		case 'w':
    278   1.1  mycroft 			num = strtol(optarg, &p, 10);
    279   1.1  mycroft 			if (*p || num <= 0)
    280   1.1  mycroft 				errx(1, "illegal -w value -- %s", optarg);
    281   1.1  mycroft 			nfsargsp->wsize = num;
    282   1.1  mycroft 			nfsargsp->flags |= NFSMNT_WSIZE;
    283   1.1  mycroft 			break;
    284   1.1  mycroft 		case 'x':
    285   1.1  mycroft 			num = strtol(optarg, &p, 10);
    286   1.1  mycroft 			if (*p || num <= 0)
    287   1.1  mycroft 				errx(1, "illegal -x value -- %s", optarg);
    288   1.1  mycroft 			nfsargsp->retrans = num;
    289   1.1  mycroft 			nfsargsp->flags |= NFSMNT_RETRANS;
    290   1.1  mycroft 			break;
    291   1.1  mycroft 		default:
    292   1.1  mycroft 			usage();
    293   1.1  mycroft 			break;
    294   1.1  mycroft 		}
    295   1.1  mycroft 	argc -= optind;
    296   1.1  mycroft 	argv += optind;
    297   1.1  mycroft 
    298   1.1  mycroft 	if (argc != 2)
    299   1.7      cgd 		usage();
    300   1.1  mycroft 
    301   1.1  mycroft 	spec = *argv++;
    302   1.1  mycroft 	name = *argv;
    303   1.1  mycroft 
    304   1.1  mycroft 	if (!getnfsargs(spec, nfsargsp))
    305   1.1  mycroft 		exit(1);
    306   1.1  mycroft 	if (mount(MOUNT_NFS, name, mntflags, nfsargsp))
    307   1.1  mycroft 		err(1, "%s", name);
    308   1.1  mycroft 	if (nfsargsp->flags & (NFSMNT_NQNFS | NFSMNT_KERB)) {
    309   1.1  mycroft 		if ((opflags & ISBGRND) == 0) {
    310   1.1  mycroft 			if (i = fork()) {
    311   1.1  mycroft 				if (i == -1)
    312   1.1  mycroft 					err(1, "nqnfs 1");
    313   1.1  mycroft 				exit(0);
    314   1.1  mycroft 			}
    315   1.1  mycroft 			(void) setsid();
    316   1.1  mycroft 			(void) close(STDIN_FILENO);
    317   1.1  mycroft 			(void) close(STDOUT_FILENO);
    318   1.1  mycroft 			(void) close(STDERR_FILENO);
    319   1.1  mycroft 			(void) chdir("/");
    320   1.1  mycroft 		}
    321   1.1  mycroft 		openlog("mount_nfs:", LOG_PID, LOG_DAEMON);
    322   1.1  mycroft 		nfssvc_flag = NFSSVC_MNTD;
    323   1.1  mycroft 		ncd.ncd_dirp = name;
    324   1.1  mycroft 		while (nfssvc(nfssvc_flag, (caddr_t)&ncd) < 0) {
    325   1.1  mycroft 			if (errno != ENEEDAUTH) {
    326   1.1  mycroft 				syslog(LOG_ERR, "nfssvc err %m");
    327   1.1  mycroft 				continue;
    328   1.1  mycroft 			}
    329   1.1  mycroft 			nfssvc_flag =
    330   1.1  mycroft 			    NFSSVC_MNTD | NFSSVC_GOTAUTH | NFSSVC_AUTHINFAIL;
    331   1.1  mycroft #ifdef KERBEROS
    332   1.1  mycroft 			/*
    333   1.1  mycroft 			 * Set up as ncd_authuid for the kerberos call.
    334   1.1  mycroft 			 * Must set ruid to ncd_authuid and reset the
    335   1.1  mycroft 			 * ticket name iff ncd_authuid is not the same
    336   1.1  mycroft 			 * as last time, so that the right ticket file
    337   1.1  mycroft 			 * is found.
    338   1.1  mycroft 			 */
    339   1.1  mycroft 			if (ncd.ncd_authuid != last_ruid) {
    340   1.1  mycroft 				krb_set_tkt_string("");
    341   1.1  mycroft 				last_ruid = ncd.ncd_authuid;
    342   1.1  mycroft 			}
    343   1.1  mycroft 			setreuid(ncd.ncd_authuid, 0);
    344   1.1  mycroft 			if (krb_mk_req(&kt, "rcmd", inst, realm, 0) ==
    345   1.1  mycroft 			    KSUCCESS &&
    346   1.1  mycroft 			    kt.length <= (RPCAUTH_MAXSIZ - 2 * NFSX_UNSIGNED)) {
    347   1.1  mycroft 				ncd.ncd_authtype = RPCAUTH_NQNFS;
    348   1.1  mycroft 				ncd.ncd_authlen = kt.length;
    349   1.1  mycroft 				ncd.ncd_authstr = (char *)kt.dat;
    350   1.1  mycroft 				nfssvc_flag = NFSSVC_MNTD | NFSSVC_GOTAUTH;
    351   1.1  mycroft 			}
    352   1.1  mycroft 			setreuid(0, 0);
    353   1.1  mycroft #endif /* KERBEROS */
    354   1.1  mycroft 		}
    355   1.1  mycroft 	}
    356   1.1  mycroft 	exit(0);
    357   1.1  mycroft }
    358   1.1  mycroft 
    359   1.1  mycroft int
    360   1.1  mycroft getnfsargs(spec, nfsargsp)
    361   1.1  mycroft 	char *spec;
    362   1.1  mycroft 	struct nfs_args *nfsargsp;
    363   1.1  mycroft {
    364   1.1  mycroft 	register CLIENT *clp;
    365   1.1  mycroft 	struct hostent *hp;
    366   1.1  mycroft 	static struct sockaddr_in saddr;
    367   1.1  mycroft #ifdef ISO
    368   1.1  mycroft 	static struct sockaddr_iso isoaddr;
    369   1.1  mycroft 	struct iso_addr *isop;
    370   1.1  mycroft 	int isoflag = 0;
    371   1.1  mycroft #endif
    372   1.1  mycroft 	struct timeval pertry, try;
    373   1.1  mycroft 	enum clnt_stat clnt_stat;
    374   1.1  mycroft 	int so = RPC_ANYSOCK, i;
    375   1.1  mycroft 	char *hostp, *delimp;
    376   1.1  mycroft #ifdef KERBEROS
    377   1.1  mycroft 	char *cp;
    378   1.1  mycroft #endif
    379   1.1  mycroft 	u_short tport;
    380   1.1  mycroft 	static struct nfhret nfhret;
    381   1.1  mycroft 	static char nam[MNAMELEN + 1];
    382   1.1  mycroft 
    383   1.1  mycroft 	strncpy(nam, spec, MNAMELEN);
    384   1.1  mycroft 	nam[MNAMELEN] = '\0';
    385   1.1  mycroft 	if ((delimp = strchr(spec, '@')) != NULL) {
    386   1.1  mycroft 		hostp = delimp + 1;
    387   1.1  mycroft 	} else if ((delimp = strchr(spec, ':')) != NULL) {
    388   1.1  mycroft 		hostp = spec;
    389   1.1  mycroft 		spec = delimp + 1;
    390   1.1  mycroft 	} else {
    391   1.1  mycroft 		warnx("no <host>:<dirpath> or <dirpath>@<host> spec");
    392   1.1  mycroft 		return (0);
    393   1.1  mycroft 	}
    394   1.1  mycroft 	*delimp = '\0';
    395   1.1  mycroft 	/*
    396   1.1  mycroft 	 * DUMB!! Until the mount protocol works on iso transport, we must
    397   1.1  mycroft 	 * supply both an iso and an inet address for the host.
    398   1.1  mycroft 	 */
    399   1.1  mycroft #ifdef ISO
    400   1.1  mycroft 	if (!strncmp(hostp, "iso=", 4)) {
    401   1.1  mycroft 		u_short isoport;
    402   1.1  mycroft 
    403   1.1  mycroft 		hostp += 4;
    404   1.1  mycroft 		isoflag++;
    405   1.1  mycroft 		if ((delimp = strchr(hostp, '+')) == NULL) {
    406   1.1  mycroft 			warnx("no iso+inet address");
    407   1.1  mycroft 			return (0);
    408   1.1  mycroft 		}
    409   1.1  mycroft 		*delimp = '\0';
    410   1.1  mycroft 		if ((isop = iso_addr(hostp)) == NULL) {
    411   1.1  mycroft 			warnx("bad ISO address");
    412   1.1  mycroft 			return (0);
    413   1.1  mycroft 		}
    414   1.6  mycroft 		memset(&isoaddr, 0, sizeof (isoaddr));
    415   1.6  mycroft 		memcpy(&isoaddr.siso_addr, isop, sizeof (struct iso_addr));
    416   1.1  mycroft 		isoaddr.siso_len = sizeof (isoaddr);
    417   1.1  mycroft 		isoaddr.siso_family = AF_ISO;
    418   1.1  mycroft 		isoaddr.siso_tlen = 2;
    419   1.1  mycroft 		isoport = htons(NFS_PORT);
    420   1.6  mycroft 		memcpy(TSEL(&isoaddr), &isoport, isoaddr.siso_tlen);
    421   1.1  mycroft 		hostp = delimp + 1;
    422   1.1  mycroft 	}
    423   1.1  mycroft #endif /* ISO */
    424   1.1  mycroft 
    425   1.1  mycroft 	/*
    426   1.1  mycroft 	 * Handle an internet host address and reverse resolve it if
    427   1.1  mycroft 	 * doing Kerberos.
    428   1.1  mycroft 	 */
    429  1.10  mycroft 	if (inet_aton(hostp, &saddr.sin_addr) != 0) {
    430  1.10  mycroft 		if ((nfsargsp->flags & NFSMNT_KERB)) {
    431  1.10  mycroft 			if ((hp = gethostbyaddr((char *)&saddr.sin_addr.s_addr,
    432  1.10  mycroft 			    sizeof (u_long), AF_INET)) == (struct hostent *)0) {
    433  1.10  mycroft 				warnx("can't reverse resolve net address");
    434  1.10  mycroft 				return (0);
    435  1.10  mycroft 			}
    436   1.1  mycroft 		}
    437  1.10  mycroft 	} else {
    438  1.10  mycroft 		hp = gethostbyname(hostp);
    439  1.10  mycroft 		if (hp == NULL) {
    440  1.10  mycroft 			warnx("can't get net id for host");
    441   1.1  mycroft 			return (0);
    442   1.1  mycroft 		}
    443   1.6  mycroft 		memcpy(&saddr.sin_addr, hp->h_addr, hp->h_length);
    444  1.10  mycroft 	}
    445   1.1  mycroft #ifdef KERBEROS
    446   1.1  mycroft 	if (nfsargsp->flags & NFSMNT_KERB) {
    447   1.1  mycroft 		strncpy(inst, hp->h_name, INST_SZ);
    448   1.1  mycroft 		inst[INST_SZ - 1] = '\0';
    449   1.1  mycroft 		if (cp = strchr(inst, '.'))
    450   1.1  mycroft 			*cp = '\0';
    451   1.1  mycroft 	}
    452   1.1  mycroft #endif /* KERBEROS */
    453   1.1  mycroft 
    454   1.1  mycroft 	nfhret.stat = EACCES;	/* Mark not yet successful */
    455   1.1  mycroft 	while (retrycnt > 0) {
    456   1.1  mycroft 		saddr.sin_family = AF_INET;
    457   1.1  mycroft 		saddr.sin_port = htons(PMAPPORT);
    458   1.1  mycroft 		if ((tport = pmap_getport(&saddr, RPCPROG_NFS,
    459   1.5  mycroft 		    NFS_VER2, nfsargsp->sotype == SOCK_STREAM ? IPPROTO_TCP :
    460   1.5  mycroft 		    IPPROTO_UDP)) == 0) {
    461   1.1  mycroft 			if ((opflags & ISBGRND) == 0)
    462   1.1  mycroft 				clnt_pcreateerror("NFS Portmap");
    463   1.1  mycroft 		} else {
    464   1.1  mycroft 			saddr.sin_port = 0;
    465   1.1  mycroft 			pertry.tv_sec = 10;
    466   1.1  mycroft 			pertry.tv_usec = 0;
    467   1.5  mycroft 			if ((clp = (nfsargsp->sotype == SOCK_STREAM ?
    468   1.5  mycroft 			    clnttcp_create(&saddr, RPCPROG_MNT, RPCMNT_VER1,
    469   1.5  mycroft 					   &so, 0, 0) :
    470   1.5  mycroft 			    clntudp_create(&saddr, RPCPROG_MNT, RPCMNT_VER1,
    471   1.5  mycroft 					   pertry, &so))) == NULL) {
    472   1.1  mycroft 				if ((opflags & ISBGRND) == 0)
    473   1.1  mycroft 					clnt_pcreateerror("Cannot MNT PRC");
    474   1.1  mycroft 			} else {
    475   1.1  mycroft 				clp->cl_auth = authunix_create_default();
    476   1.1  mycroft 				try.tv_sec = 10;
    477   1.1  mycroft 				try.tv_usec = 0;
    478   1.1  mycroft 				clnt_stat = clnt_call(clp, RPCMNT_MOUNT,
    479   1.1  mycroft 				    xdr_dir, spec, xdr_fh, &nfhret, try);
    480   1.1  mycroft 				if (clnt_stat != RPC_SUCCESS) {
    481   1.1  mycroft 					if ((opflags & ISBGRND) == 0)
    482   1.1  mycroft 						warnx("%s", clnt_sperror(clp,
    483   1.1  mycroft 						    "bad MNT RPC"));
    484   1.1  mycroft 				} else {
    485   1.1  mycroft 					auth_destroy(clp->cl_auth);
    486   1.1  mycroft 					clnt_destroy(clp);
    487   1.1  mycroft 					retrycnt = 0;
    488   1.1  mycroft 				}
    489   1.1  mycroft 			}
    490   1.1  mycroft 		}
    491   1.1  mycroft 		if (--retrycnt > 0) {
    492   1.1  mycroft 			if (opflags & BGRND) {
    493   1.1  mycroft 				opflags &= ~BGRND;
    494   1.1  mycroft 				if (i = fork()) {
    495   1.1  mycroft 					if (i == -1)
    496   1.1  mycroft 						err(1, "nqnfs 2");
    497   1.1  mycroft 					exit(0);
    498   1.1  mycroft 				}
    499   1.1  mycroft 				(void) setsid();
    500   1.1  mycroft 				(void) close(STDIN_FILENO);
    501   1.1  mycroft 				(void) close(STDOUT_FILENO);
    502   1.1  mycroft 				(void) close(STDERR_FILENO);
    503   1.1  mycroft 				(void) chdir("/");
    504   1.1  mycroft 				opflags |= ISBGRND;
    505   1.1  mycroft 			}
    506   1.1  mycroft 			sleep(60);
    507   1.1  mycroft 		}
    508   1.1  mycroft 	}
    509   1.1  mycroft 	if (nfhret.stat) {
    510   1.1  mycroft 		if (opflags & ISBGRND)
    511   1.1  mycroft 			exit(1);
    512   1.4  mycroft 		errno = nfhret.stat;
    513   1.1  mycroft 		warn("can't access %s", spec);
    514   1.1  mycroft 		return (0);
    515   1.1  mycroft 	}
    516   1.1  mycroft 	saddr.sin_port = htons(tport);
    517   1.1  mycroft #ifdef ISO
    518   1.1  mycroft 	if (isoflag) {
    519   1.1  mycroft 		nfsargsp->addr = (struct sockaddr *) &isoaddr;
    520   1.1  mycroft 		nfsargsp->addrlen = sizeof (isoaddr);
    521   1.1  mycroft 	} else
    522   1.1  mycroft #endif /* ISO */
    523   1.1  mycroft 	{
    524   1.1  mycroft 		nfsargsp->addr = (struct sockaddr *) &saddr;
    525   1.1  mycroft 		nfsargsp->addrlen = sizeof (saddr);
    526   1.1  mycroft 	}
    527   1.1  mycroft 	nfsargsp->fh = &nfhret.nfh;
    528   1.1  mycroft 	nfsargsp->hostname = nam;
    529   1.1  mycroft 	return (1);
    530   1.1  mycroft }
    531   1.1  mycroft 
    532   1.1  mycroft /*
    533   1.1  mycroft  * xdr routines for mount rpc's
    534   1.1  mycroft  */
    535   1.1  mycroft int
    536   1.1  mycroft xdr_dir(xdrsp, dirp)
    537   1.1  mycroft 	XDR *xdrsp;
    538   1.1  mycroft 	char *dirp;
    539   1.1  mycroft {
    540   1.1  mycroft 	return (xdr_string(xdrsp, &dirp, RPCMNT_PATHLEN));
    541   1.1  mycroft }
    542   1.1  mycroft 
    543   1.1  mycroft int
    544   1.1  mycroft xdr_fh(xdrsp, np)
    545   1.1  mycroft 	XDR *xdrsp;
    546   1.1  mycroft 	struct nfhret *np;
    547   1.1  mycroft {
    548   1.1  mycroft 	if (!xdr_u_long(xdrsp, &(np->stat)))
    549   1.1  mycroft 		return (0);
    550   1.1  mycroft 	if (np->stat)
    551   1.1  mycroft 		return (1);
    552   1.1  mycroft 	return (xdr_opaque(xdrsp, (caddr_t)&(np->nfh), NFSX_FH));
    553   1.1  mycroft }
    554   1.1  mycroft 
    555   1.1  mycroft __dead void
    556   1.1  mycroft usage()
    557   1.1  mycroft {
    558   1.1  mycroft 	(void)fprintf(stderr, "usage: mount_nfs %s\n%s\n%s\n%s\n",
    559   1.1  mycroft "[-bcdiKklMPqsT] [-a maxreadahead] [-D deadthresh]",
    560   1.1  mycroft "\t[-g maxgroups] [-L leaseterm] [-m realm] [-o options] [-R retrycnt]",
    561   1.1  mycroft "\t[-r readsize] [-t timeout] [-w writesize] [-x retrans]",
    562   1.1  mycroft "\trhost:path node");
    563   1.1  mycroft 	exit(1);
    564   1.1  mycroft }
    565