int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
{
	static const char digits[] = "0123456789";
	u_char *label, *bp, *eom;
	int c, n, escaped, e = 0;
	char *cp;

	escaped = 0;
	bp = dst;
	eom = dst + dstsiz;
	label = bp++;

	while ((c = *src++) != 0) {
		if (escaped) {
			if (c == '[') { /*%< start a bit string label */
				cp = strchr(src, ']');
				if (cp == NULL) {
					errno = EINVAL; /*%< ??? */
					return -1;
				}
				e = encode_bitstring(&src, cp + 2,
							 &label, &bp, eom);
				if (e != 0) {
					errno = e;
					return -1;
				}
				escaped = 0;
				label = bp++;
				c = *src++;
				if (c == '\0')
					goto done;
				if (c != '.') {
					errno = EINVAL;
					return -1;
				}
				continue;
			}
			cp = strchr(digits, c);
			if (cp != NULL) {
				n = (cp - digits) * 100;
				c = *src++;
				if (c == '\0')
					goto ret_EMSGSIZE;
				cp = strchr(digits, c);
				if (cp == NULL)
					goto ret_EMSGSIZE;
				n += (cp - digits) * 10;
				c = *src++;
				if (c == '\0')
					goto ret_EMSGSIZE;
				cp = strchr(digits, c);
				if (cp == NULL)
					goto ret_EMSGSIZE;
				n += (cp - digits);
				if (n > 255)
					goto ret_EMSGSIZE;
				c = n;
			}
			escaped = 0;
		} else if (c == '\\') {
			escaped = 1;
			continue;
		} else if (c == '.') {
			c = (bp - label - 1);
			if ((c & NS_CMPRSFLGS) != 0) {  /*%< Label too big. */
				goto ret_EMSGSIZE;
			}
			if (label >= eom) {
				goto ret_EMSGSIZE;
			}
			*label = c;
			/* Fully qualified ? */
			if (*src == '\0') {
				if (c != 0) {
					if (bp >= eom) {
						goto ret_EMSGSIZE;
					}
					*bp++ = '\0';
				}
				if ((bp - dst) > MAXCDNAME) {
					goto ret_EMSGSIZE;
				}

				return 1;
			}
			if (c == 0 || *src == '.') {
				goto ret_EMSGSIZE;
			}
			label = bp++;
			continue;
		}
		if (bp >= eom) {
			goto ret_EMSGSIZE;
		}
		*bp++ = (u_char)c;
	}
	c = (bp - label - 1);
	if ((c & NS_CMPRSFLGS) != 0) {	  /*%< Label too big. */
		goto ret_EMSGSIZE;
	}
 done:
	if (label >= eom) {
		goto ret_EMSGSIZE;
	}
	*label = c;
	if (c != 0) {
		if (bp >= eom) {
			goto ret_EMSGSIZE;
		}
		*bp++ = 0;
	}
	if ((bp - dst) > MAXCDNAME) {   /*%< src too big */
		goto ret_EMSGSIZE;
	}

	return 0;

 ret_EMSGSIZE:
	errno = EMSGSIZE;
	return -1;
}
int ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
{
	static const char digits[] = "0123456789";
	u_char *label, *bp, *eom;
	int c, n, escaped, e = 0;
	char *cp;

	escaped = 0;
	bp = dst;
	eom = dst + dstsiz;
	label = bp++;

	while ((c = *src++) != 0) {
		if (escaped) {
			if (c == '[') {  
				cp = strchr(src, ']');
				if (cp == NULL) {
					errno = EINVAL;  
					return -1;
				}
				e = encode_bitstring(&src, cp + 2,
							 &label, &bp, eom);
				if (e != 0) {
					errno = e;
					return -1;
				}
				escaped = 0;
				label = bp++;
				c = *src++;
				if (c == '\0')
					goto done;
				if (c != '.') {
					errno = EINVAL;
					return -1;
				}
				continue;
			}
			cp = strchr(digits, c);
			if (cp != NULL) {
				n = (cp - digits) * 100;
				c = *src++;
				if (c == '\0')
					goto ret_EMSGSIZE;
				cp = strchr(digits, c);
				if (cp == NULL)
					goto ret_EMSGSIZE;
				n += (cp - digits) * 10;
				c = *src++;
				if (c == '\0')
					goto ret_EMSGSIZE;
				cp = strchr(digits, c);
				if (cp == NULL)
					goto ret_EMSGSIZE;
				n += (cp - digits);
				if (n > 255)
					goto ret_EMSGSIZE;
				c = n;
			}
			escaped = 0;
		} else if (c == '\\') {
			escaped = 1;
			continue;
		} else if (c == '.') {
			c = (bp - label - 1);
			if ((c & NS_CMPRSFLGS) != 0) {   
				goto ret_EMSGSIZE;
			}
			if (label >= eom) {
				goto ret_EMSGSIZE;
			}
			*label = c;
			 
			if (*src == '\0') {
				if (c != 0) {
					if (bp >= eom) {
						goto ret_EMSGSIZE;
					}
					*bp++ = '\0';
				}
				if ((bp - dst) > MAXCDNAME) {
					goto ret_EMSGSIZE;
				}

				return 1;
			}
			if (c == 0 || *src == '.') {
				goto ret_EMSGSIZE;
			}
			label = bp++;
			continue;
		}
		if (bp >= eom) {
			goto ret_EMSGSIZE;
		}
		*bp++ = (u_char)c;
	}
	c = (bp - label - 1);
	if ((c & NS_CMPRSFLGS) != 0) {	   
		goto ret_EMSGSIZE;
	}
 done:
	if (label >= eom) {
		goto ret_EMSGSIZE;
	}
	*label = c;
	if (c != 0) {
		if (bp >= eom) {
			goto ret_EMSGSIZE;
		}
		*bp++ = 0;
	}
	if ((bp - dst) > MAXCDNAME) {    
		goto ret_EMSGSIZE;
	}

	return 0;

 ret_EMSGSIZE:
	errno = EMSGSIZE;
	return -1;
}