--- src/sbin/mount_nfs/mount_nfs.c- Mon Nov 20 03:18:26 2006 +++ src/sbin/mount_nfs/mount_nfs.c Wed May 16 07:39:46 2007 @@ -165,7 +165,10 @@ u_short port_no = 0; int force2 = 0; int force3 = 0; +int nflag, vflag; +void printnfsargs(struct nfs_args *nfsargsp); +int gethargs(char *hargs, char *spec, struct nfs_args *nfsargsp); int getnfsargs(char *, struct nfs_args *); void set_rpc_maxgrouplist(int); __dead void usage(void); @@ -181,6 +184,7 @@ int mntflags, num; char name[MAXPATHLEN], *options = NULL, *spec; const char *p; + char *hargs = NULL; union mntval value; retrycnt = DEF_RETRY; @@ -189,7 +193,7 @@ nfsargs = nfsdefargs; nfsargsp = &nfsargs; while ((c = getopt(argc, argv, - "23a:bcdD:g:I:iL:lo:PR:r:sTt:w:x:U")) != -1) + "23a:bcdD:g:h:I:iL:lno:PR:r:sTt:vw:x:U")) != -1) switch (c) { case '3': if (force2) @@ -229,6 +233,9 @@ nfsargsp->maxgrouplist = num; nfsargsp->flags |= NFSMNT_MAXGRPS; break; + case 'h': + hargs = optarg; + break; case 'I': num = (int) strtonum(optarg, 1, INT_MAX, &p); if (p) @@ -245,6 +252,9 @@ case 'l': nfsargsp->flags |= NFSMNT_RDIRPLUS; break; + case 'n': + nflag = 1; + break; case 'o': options = optarg; while (options != NULL) { @@ -352,6 +362,9 @@ nfsargsp->timeo = num; nfsargsp->flags |= NFSMNT_TIMEO; break; + case 'v': + vflag = 1; + break; case 'w': num = (int) strtonum(optarg, 1, INT_MAX, &p); if (p) @@ -383,15 +396,80 @@ if (realpath(*argv, name) == NULL) err(1, "realpath %s", *argv); - if (!getnfsargs(spec, nfsargsp)) - exit(1); - if (mount(MOUNT_NFS, name, mntflags, nfsargsp)) { + if (hargs) { + if (!gethargs(hargs, spec, nfsargsp)) + exit(1); + } else { + if (!getnfsargs(spec, nfsargsp)) + exit(1); + } + if (vflag) + printnfsargs(nfsargsp); + if (!nflag && mount(MOUNT_NFS, name, mntflags, nfsargsp)) { if (errno == EOPNOTSUPP) errx(1, "%s: Filesystem not supported by kernel", name); else err(1, "%s", name); } exit(0); +} + +char * +fhtoa(u_char *fh, int fhn) +{ + int i; + static char s[NFSX_V3FHMAX * 2 + 2]; + + s[0] = '\0'; + for (i = 0; i < fhn; i++) + snprintf(&s[i * 2], sizeof s - (i * 2), "%02.2x", (int) fh[i]); + return s; +} + +void +printnfsargs(struct nfs_args *nfsargsp) +{ + struct sockaddr_in *saddrp = (struct sockaddr_in *) nfsargsp->addr; + + printf("%s:%d:%s %s\n", + inet_ntoa(saddrp->sin_addr), ntohs(saddrp->sin_port), + fhtoa(nfsargsp->fh, nfsargsp->fhsize), nfsargsp->hostname); +} + +int +gethargs(char *hargs, char *spec, struct nfs_args *nfsargsp) +{ + static char nam[MNAMELEN + 1]; + char hostp[16], fhs[NFSX_V3FHMAX * 2 + 2]; + static u_char fh[NFSX_V3FHMAX]; + unsigned short port; + static struct sockaddr_in saddr; + int b, fhn = 0; + + if (strlcpy(nam, spec, sizeof(nam)) >= sizeof(nam)) { + errx(1, "hostname too long"); + } + + if (sscanf(hargs, "%[^:]:%hu:%[^:]", hostp, &port, fhs) != 3) + return 0; + + inet_aton(hostp, &saddr.sin_addr); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + + while (1) { + if (sscanf(&fhs[fhn * 2], "%2x", &b) != 1) + break; + fh[fhn++] = b; + } + + nfsargsp->addr = (struct sockaddr *) &saddr; + nfsargsp->addrlen = sizeof (saddr); + nfsargsp->fh = fh; + nfsargsp->fhsize = fhn; + nfsargsp->hostname = nam; + + return 1; } int