changeset 3767:9d24e84a65d8

4759334 different IPv6 syntax in mount & automount
author js195444
date Tue, 06 Mar 2007 07:39:17 -0800
parents 0e6dc235b6f9
children 3648e0773d4b
files usr/src/cmd/fs.d/autofs/auto_subr.c usr/src/cmd/fs.d/autofs/autod_nfs.c usr/src/cmd/fs.d/autofs/automount.h
diffstat 3 files changed, 94 insertions(+), 24 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fs.d/autofs/auto_subr.c	Mon Mar 05 18:48:06 2007 -0800
+++ b/usr/src/cmd/fs.d/autofs/auto_subr.c	Tue Mar 06 07:39:17 2007 -0800
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -288,13 +288,12 @@
 }
 
 /*
- * Gets the next token from the string "p" and copies
- * it into "w".  Both "wq" and "w" are quote vectors
- * for "w" and "p".  Delim is the character to be used
- * as a delimiter for the scan.  A space means "whitespace".
- * The call to getword must provide buffers w and wq of size at
- * least wordsz. getword() will pass strings of maximum length
- * (wordsz-1), since it needs to null terminate the string.
+ * Gets the next token from the string "p" and copies it into "w".  The "wq" is
+ * a quote vector for "w" and is derived from "pq", which is a quote vector for
+ * "p". Delim is the character to be used as a delimiter for the scan.  A space
+ * means "whitespace". The call to getword must provide buffers w and wq of size
+ * at least wordsz. getword() will pass strings of maximum length (wordsz-1),
+ * since it needs to null terminate the string.
  * Returns 0 on ok and -1 on error.
  */
 int
@@ -651,21 +650,27 @@
 }
 
 /*
- * Removes quotes from the string "str" and returns
- * the quoting information in "qbuf". e.g.
- * original str: 'the "quick brown" f\ox'
- * unquoted str: 'the quick brown fox'
- * and the qbuf: '    ^^^^^^^^^^^  ^ '
+ * Removes backslashes, quotes and brackets from the string "str"
+ * and returns the quoting information in "qbuf". Character is
+ * considered escaped when it is
+ *
+ * 	preceded with '\'	e.g. \a
+ * 	within quotes		e.g. "string"
+ * 	a ':' in brackets 	e.g. [an:ip:6::ad::d:re:s:s]
+ *
+ * original str: 'the "brown" f\ox said: [fe80::20a:e4ff:fe35:8b0d]'
+ * unquoted str: 'the brown fox said: [fe80::20a:e4ff:fe35:8b0d]'
+ * and the qbuf: '    ^^^^^  ^             ^^   ^    ^    ^     '
  */
 void
 unquote(str, qbuf)
 	char *str, *qbuf;
 {
-	register int escaped, inquote, quoted;
+	register int escaped, inquote, inbracket, quoted;
 	register char *ip, *bp, *qp;
 	char buf[LINESZ];
 
-	escaped = inquote = quoted = 0;
+	escaped = inquote = inbracket = quoted = 0;
 
 	for (ip = str, bp = buf, qp = qbuf; *ip; ip++) {
 		if (!escaped) {
@@ -678,20 +683,45 @@
 				inquote = !inquote;
 				quoted++;
 				continue;
+			} else
+			if (*ip == '[') {
+				inbracket++;
+				quoted++;
+			} else
+			if (*ip == ']') {
+				if (inbracket > 0) inbracket--;
 			}
 		}
 
 		*bp++ = *ip;
-		*qp++ = (inquote || escaped) ? '^' : ' ';
+		*qp++ = (inquote || escaped) ? '^'
+				: ((inbracket && (*ip == ':')) ? '^' : ' ');
 		escaped = 0;
 	}
+
 	*bp = '\0';
 	*qp = '\0';
+
 	if (quoted)
 		(void) strcpy(str, buf);
 }
 
 /*
+ * If str is enclosed in [brackets], trim them off.
+ */
+void
+unbracket(s)
+	char **s;
+{
+	char *b = *s + strlen(*s) - 1;
+
+	if (*b == ']')
+		*b = '\0';
+	if (**s == '[')
+		(*s)++;
+}
+
+/*
  * Removes trailing spaces from string "s".
  */
 void
--- a/usr/src/cmd/fs.d/autofs/autod_nfs.c	Mon Mar 05 18:48:06 2007 -0800
+++ b/usr/src/cmd/fs.d/autofs/autod_nfs.c	Tue Mar 06 07:39:17 2007 -0800
@@ -671,7 +671,7 @@
 	int retries;
 	char *nfs_proto = NULL;
 	uint_t nfs_port = 0;
-	char *p, *host, *dir;
+	char *p, *host, *rhost, *dir;
 	struct mapfs *mfs = NULL;
 	int error, last_error = 0;
 	int replicated;
@@ -855,7 +855,18 @@
 		if (mfs->mfs_ignore)
 			continue;
 
-		host = mfs->mfs_host;
+		/*
+		 * If the host is '[a:d:d:r:e:s:s'],
+		 * only use 'a:d:d:r:e:s:s' for communication
+		 */
+		host = strdup(mfs->mfs_host);
+		if (host == NULL) {
+			syslog(LOG_ERR, "nfsmount: no memory");
+			last_error = NFSERR_IO;
+			goto out;
+		}
+		unbracket(&host);
+
 		(void) memcpy(&mfssnego, &mfssnego_init, sizeof (mfs_snego_t));
 
 		if (use_pubfh == TRUE || mfs->mfs_flags & MFS_URL) {
@@ -1026,6 +1037,8 @@
 			}
 		}
 
+		free(host);
+
 		switch (vers) {
 		case NFS_V4: v4cnt++; break;
 		case NFS_V3: v3cnt++; break;
@@ -1052,11 +1065,12 @@
 		 * If the mount is not replicated, we don't want to
 		 * ping every entry, so we'll stop here.  This means
 		 * that we may have to go back to "nextentry" above
-		 * to consider another entry if there we can't get
+		 * to consider another entry if we can't get
 		 * all the way to mount(2) with this one.
 		 */
 		if (!replicated)
 			break;
+
 	}
 
 	if (nfsvers == 0) {
@@ -1142,7 +1156,21 @@
 		vers = mountversmax;
 		host = mfs->mfs_host;
 		dir = mfs->mfs_dir;
-		(void) sprintf(remname, "%s:%s", host, dir);
+
+		/*
+		 * Remember the possible '[a:d:d:r:e:s:s]' as the address to be
+		 * later passed to mount(2) and used in the mnttab line, but
+		 * only use 'a:d:d:r:e:s:s' for communication
+		 */
+		rhost = strdup(host);
+		if (rhost == NULL) {
+			syslog(LOG_ERR, "nfsmount: no memory");
+			last_error = NFSERR_IO;
+			goto out;
+		}
+		unbracket(&host);
+
+		(void) sprintf(remname, "%s:%s", rhost, dir);
 		if (trace > 4 && replicated)
 			trace_prt(1, "	nfsmount: examining %s\n", remname);
 
@@ -1798,8 +1826,13 @@
 
 		argp->flags |= NFSMNT_NEWARGS;
 		argp->flags |= NFSMNT_INT;	/* default is "intr" */
+		argp->flags |= NFSMNT_HOSTNAME;
 		argp->hostname = strdup(host);
-		argp->flags |= NFSMNT_HOSTNAME;
+		if (argp->hostname == NULL) {
+			syslog(LOG_ERR, "nfsmount: no memory");
+			last_error = NFSERR_IO;
+			goto out;
+		}
 
 		/*
 		 * In this case, we want NFSv4 to behave like
@@ -2192,7 +2225,7 @@
 					mnttabcnt += strlen(remname) + 2;
 				} else {
 					*p = '\0';
-					mnttabcnt += strlen(host) + 2;
+					mnttabcnt += strlen(rhost) + 2;
 				}
 				if ((tmp = realloc(mnttabtext,
 				    mnttabcnt)) != NULL) {
@@ -3349,7 +3382,7 @@
 	int attempts,
 	rpcvers_t *versp,
 	rpcvers_t versmin,
-	ushort_t port,			/* may be zeor */
+	ushort_t port,			/* may be zero */
 	bool_t usepub,
 	char *path,
 	char *proto)
@@ -3362,9 +3395,15 @@
 	rpcvers_t versmax;	/* maximum version to try against server */
 	rpcvers_t outvers;	/* version supported by host on last call */
 	rpcvers_t vers_to_try;	/* to try different versions against host */
-	char *hostname = hostpart;
+	char *hostname;
 	struct netconfig *nconf;
 
+	hostname = strdup(hostpart);
+	if (hostname == NULL) {
+		return (RPC_SYSTEMERROR);
+	}
+	unbracket(&hostname);
+
 	if (path != NULL && strcmp(hostname, "nfs") == 0 &&
 	    strncmp(path, "//", 2) == 0) {
 		char *sport;
--- a/usr/src/cmd/fs.d/autofs/automount.h	Mon Mar 05 18:48:06 2007 -0800
+++ b/usr/src/cmd/fs.d/autofs/automount.h	Tue Mar 06 07:39:17 2007 -0800
@@ -257,6 +257,7 @@
 				char *, uint_t, bool_t);
 extern int macro_expand(char *, char *, char *, int);
 extern void unquote(char *, char *);
+extern void unbracket(char **);
 extern void trim(char *);
 extern char *get_line(FILE *, char *, char *, int);
 extern int getword(char *, char *, char **, char **, char, int);