other-licenses/android/res_debug.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/other-licenses/android/res_debug.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1201 @@
     1.4 +/*	$NetBSD: res_debug.c,v 1.7 2004/11/07 02:25:01 christos Exp $	*/
     1.5 +
     1.6 +/*
     1.7 + * Copyright (c) 1985
     1.8 + *    The Regents of the University of California.  All rights reserved.
     1.9 + *
    1.10 + * Redistribution and use in source and binary forms, with or without
    1.11 + * modification, are permitted provided that the following conditions
    1.12 + * are met:
    1.13 + * 1. Redistributions of source code must retain the above copyright
    1.14 + *    notice, this list of conditions and the following disclaimer.
    1.15 + * 2. Redistributions in binary form must reproduce the above copyright
    1.16 + *    notice, this list of conditions and the following disclaimer in the
    1.17 + *    documentation and/or other materials provided with the distribution.
    1.18 + * 3. All advertising materials mentioning features or use of this software
    1.19 + *    must display the following acknowledgement:
    1.20 + * 	This product includes software developed by the University of
    1.21 + * 	California, Berkeley and its contributors.
    1.22 + * 4. Neither the name of the University nor the names of its contributors
    1.23 + *    may be used to endorse or promote products derived from this software
    1.24 + *    without specific prior written permission.
    1.25 + *
    1.26 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    1.27 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    1.28 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    1.29 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    1.30 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    1.31 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    1.32 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    1.33 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    1.34 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    1.35 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    1.36 + * SUCH DAMAGE.
    1.37 + */
    1.38 +
    1.39 +/*
    1.40 + * Portions Copyright (c) 1993 by Digital Equipment Corporation.
    1.41 + *
    1.42 + * Permission to use, copy, modify, and distribute this software for any
    1.43 + * purpose with or without fee is hereby granted, provided that the above
    1.44 + * copyright notice and this permission notice appear in all copies, and that
    1.45 + * the name of Digital Equipment Corporation not be used in advertising or
    1.46 + * publicity pertaining to distribution of the document or software without
    1.47 + * specific, written prior permission.
    1.48 + *
    1.49 + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
    1.50 + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
    1.51 + * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
    1.52 + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
    1.53 + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
    1.54 + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
    1.55 + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
    1.56 + * SOFTWARE.
    1.57 + */
    1.58 +
    1.59 +/*
    1.60 + * Portions Copyright (c) 1995 by International Business Machines, Inc.
    1.61 + *
    1.62 + * International Business Machines, Inc. (hereinafter called IBM) grants
    1.63 + * permission under its copyrights to use, copy, modify, and distribute this
    1.64 + * Software with or without fee, provided that the above copyright notice and
    1.65 + * all paragraphs of this notice appear in all copies, and that the name of IBM
    1.66 + * not be used in connection with the marketing of any product incorporating
    1.67 + * the Software or modifications thereof, without specific, written prior
    1.68 + * permission.
    1.69 + *
    1.70 + * To the extent it has a right to do so, IBM grants an immunity from suit
    1.71 + * under its patents, if any, for the use, sale or manufacture of products to
    1.72 + * the extent that such products are used for performing Domain Name System
    1.73 + * dynamic updates in TCP/IP networks by means of the Software.  No immunity is
    1.74 + * granted for any product per se or for any other function of any product.
    1.75 + *
    1.76 + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
    1.77 + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
    1.78 + * PARTICULAR PURPOSE.  IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
    1.79 + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
    1.80 + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
    1.81 + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
    1.82 + */
    1.83 +
    1.84 +/*
    1.85 + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
    1.86 + * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
    1.87 + *
    1.88 + * Permission to use, copy, modify, and distribute this software for any
    1.89 + * purpose with or without fee is hereby granted, provided that the above
    1.90 + * copyright notice and this permission notice appear in all copies.
    1.91 + *
    1.92 + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
    1.93 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
    1.94 + * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
    1.95 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    1.96 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    1.97 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
    1.98 + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    1.99 + */
   1.100 +
   1.101 +/*
   1.102 + * This version of this file is derived from Android 2.3 "Gingerbread",
   1.103 + * which contains uncredited changes by Android/Google developers.  It has
   1.104 + * been modified in 2011 for use in the Android build of Mozilla Firefox by
   1.105 + * Mozilla contributors (including Michael Edwards <m.k.edwards@gmail.com>,
   1.106 + * and Steve Workman <sjhworkman@gmail.com>).
   1.107 + * These changes are offered under the same license as the original NetBSD
   1.108 + * file, whose copyright and license are unchanged above.
   1.109 + */
   1.110 +
   1.111 +#define ANDROID_CHANGES 1
   1.112 +#define MOZILLA_NECKO_EXCLUDE_CODE 1
   1.113 +
   1.114 +#include <sys/cdefs.h>
   1.115 +#if defined(LIBC_SCCS) && !defined(lint)
   1.116 +#ifdef notdef
   1.117 +static const char sccsid[] = "@(#)res_debug.c	8.1 (Berkeley) 6/4/93";
   1.118 +static const char rcsid[] = "Id: res_debug.c,v 1.3.2.5.4.5 2004/07/28 20:16:46 marka Exp";
   1.119 +#else
   1.120 +__RCSID("$NetBSD: res_debug.c,v 1.7 2004/11/07 02:25:01 christos Exp $");
   1.121 +#endif
   1.122 +#endif /* LIBC_SCCS and not lint */
   1.123 +
   1.124 +
   1.125 +
   1.126 +#include <sys/types.h>
   1.127 +#include <sys/param.h>
   1.128 +#include <sys/socket.h>
   1.129 +
   1.130 +#include <netinet/in.h>
   1.131 +#include <arpa/inet.h>
   1.132 +#include "arpa_nameser.h"
   1.133 +
   1.134 +#include <ctype.h>
   1.135 +#include <errno.h>
   1.136 +#include <math.h>
   1.137 +#include <netdb.h>
   1.138 +#include "resolv_private.h"
   1.139 +#include <stdio.h>
   1.140 +#include <stdlib.h>
   1.141 +#include <string.h>
   1.142 +#include <time.h>
   1.143 +
   1.144 +
   1.145 +
   1.146 +#ifdef SPRINTF_CHAR
   1.147 +# define SPRINTF(x) strlen(sprintf/**/x)
   1.148 +#else
   1.149 +# define SPRINTF(x) sprintf x
   1.150 +#endif
   1.151 +
   1.152 +#ifndef MOZILLA_NECKO_EXCLUDE_CODE
   1.153 +static const char *precsize_ntoa(u_int32_t);
   1.154 +#endif
   1.155 +
   1.156 +extern const char * const _res_opcodes[];
   1.157 +extern const char * const _res_sectioncodes[];
   1.158 +
   1.159 +#ifndef MOZILLA_NECKO_EXCLUDE_CODE
   1.160 +#ifndef _LIBC
   1.161 +/*
   1.162 + * Print the current options.
   1.163 + */
   1.164 +void
   1.165 +fp_resstat(const res_state statp, FILE *file) {
   1.166 +	u_long mask;
   1.167 +
   1.168 +	fprintf(file, ";; res options:");
   1.169 +	for (mask = 1;  mask != 0U;  mask <<= 1)
   1.170 +		if (statp->options & mask)
   1.171 +			fprintf(file, " %s", p_option(mask));
   1.172 +	putc('\n', file);
   1.173 +}
   1.174 +#endif
   1.175 +#endif
   1.176 +
   1.177 +static void
   1.178 +do_section(const res_state statp,
   1.179 +	   ns_msg *handle, ns_sect section,
   1.180 +	   int pflag, FILE *file)
   1.181 +{
   1.182 +	int n, sflag, rrnum;
   1.183 +	int buflen = 2048;
   1.184 +	char *buf;
   1.185 +	ns_opcode opcode;
   1.186 +	ns_rr rr;
   1.187 +
   1.188 +	/*
   1.189 +	 * Print answer records.
   1.190 +	 */
   1.191 +	sflag = (statp->pfcode & pflag);
   1.192 +	if (statp->pfcode && !sflag)
   1.193 +		return;
   1.194 +
   1.195 +	buf = malloc((size_t)buflen);
   1.196 +	if (buf == NULL) {
   1.197 +		fprintf(file, ";; memory allocation failure\n");
   1.198 +		return;
   1.199 +	}
   1.200 +
   1.201 +	opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
   1.202 +	rrnum = 0;
   1.203 +	for (;;) {
   1.204 +		if (ns_parserr(handle, section, rrnum, &rr)) {
   1.205 +			if (errno != ENODEV)
   1.206 +				fprintf(file, ";; ns_parserr: %s\n",
   1.207 +					strerror(errno));
   1.208 +			else if (rrnum > 0 && sflag != 0 &&
   1.209 +				 (statp->pfcode & RES_PRF_HEAD1))
   1.210 +				putc('\n', file);
   1.211 +			goto cleanup;
   1.212 +		}
   1.213 +		if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1))
   1.214 +			fprintf(file, ";; %s SECTION:\n",
   1.215 +				p_section(section, opcode));
   1.216 +		if (section == ns_s_qd)
   1.217 +			fprintf(file, ";;\t%s, type = %s, class = %s\n",
   1.218 +				ns_rr_name(rr),
   1.219 +				p_type(ns_rr_type(rr)),
   1.220 +				p_class(ns_rr_class(rr)));
   1.221 +		else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
   1.222 +			u_int32_t ttl = ns_rr_ttl(rr);
   1.223 +			fprintf(file,
   1.224 +				"; EDNS: version: %u, udp=%u, flags=%04x\n",
   1.225 +				(ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff);
   1.226 +		} else {
   1.227 +			n = ns_sprintrr(handle, &rr, NULL, NULL,
   1.228 +					buf, (u_int)buflen);
   1.229 +			if (n < 0) {
   1.230 +				if (errno == ENOSPC) {
   1.231 +					free(buf);
   1.232 +					buf = NULL;
   1.233 +					if (buflen < 131072)
   1.234 +						buf = malloc((size_t)(buflen += 1024));
   1.235 +					if (buf == NULL) {
   1.236 +						fprintf(file,
   1.237 +				              ";; memory allocation failure\n");
   1.238 +					      return;
   1.239 +					}
   1.240 +					continue;
   1.241 +				}
   1.242 +				fprintf(file, ";; ns_sprintrr: %s\n",
   1.243 +					strerror(errno));
   1.244 +				goto cleanup;
   1.245 +			}
   1.246 +			fputs(buf, file);
   1.247 +			fputc('\n', file);
   1.248 +		}
   1.249 +		rrnum++;
   1.250 +	}
   1.251 + cleanup:
   1.252 +	if (buf != NULL)
   1.253 +		free(buf);
   1.254 +}
   1.255 +
   1.256 +/*
   1.257 + * Print the contents of a query.
   1.258 + * This is intended to be primarily a debugging routine.
   1.259 + */
   1.260 +void
   1.261 +res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) {
   1.262 +	ns_msg handle;
   1.263 +	int qdcount, ancount, nscount, arcount;
   1.264 +	u_int opcode, rcode, id;
   1.265 +
   1.266 +	if (ns_initparse(msg, len, &handle) < 0) {
   1.267 +		fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
   1.268 +		return;
   1.269 +	}
   1.270 +	opcode = ns_msg_getflag(handle, ns_f_opcode);
   1.271 +	rcode = ns_msg_getflag(handle, ns_f_rcode);
   1.272 +	id = ns_msg_id(handle);
   1.273 +	qdcount = ns_msg_count(handle, ns_s_qd);
   1.274 +	ancount = ns_msg_count(handle, ns_s_an);
   1.275 +	nscount = ns_msg_count(handle, ns_s_ns);
   1.276 +	arcount = ns_msg_count(handle, ns_s_ar);
   1.277 +
   1.278 +	/*
   1.279 +	 * Print header fields.
   1.280 +	 */
   1.281 +	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode)
   1.282 +		fprintf(file,
   1.283 +			";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
   1.284 +			_res_opcodes[opcode], p_rcode((int)rcode), id);
   1.285 +	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX))
   1.286 +		putc(';', file);
   1.287 +	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) {
   1.288 +		fprintf(file, "; flags:");
   1.289 +		if (ns_msg_getflag(handle, ns_f_qr))
   1.290 +			fprintf(file, " qr");
   1.291 +		if (ns_msg_getflag(handle, ns_f_aa))
   1.292 +			fprintf(file, " aa");
   1.293 +		if (ns_msg_getflag(handle, ns_f_tc))
   1.294 +			fprintf(file, " tc");
   1.295 +		if (ns_msg_getflag(handle, ns_f_rd))
   1.296 +			fprintf(file, " rd");
   1.297 +		if (ns_msg_getflag(handle, ns_f_ra))
   1.298 +			fprintf(file, " ra");
   1.299 +		if (ns_msg_getflag(handle, ns_f_z))
   1.300 +			fprintf(file, " ??");
   1.301 +		if (ns_msg_getflag(handle, ns_f_ad))
   1.302 +			fprintf(file, " ad");
   1.303 +		if (ns_msg_getflag(handle, ns_f_cd))
   1.304 +			fprintf(file, " cd");
   1.305 +	}
   1.306 +	if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) {
   1.307 +		fprintf(file, "; %s: %d",
   1.308 +			p_section(ns_s_qd, (int)opcode), qdcount);
   1.309 +		fprintf(file, ", %s: %d",
   1.310 +			p_section(ns_s_an, (int)opcode), ancount);
   1.311 +		fprintf(file, ", %s: %d",
   1.312 +			p_section(ns_s_ns, (int)opcode), nscount);
   1.313 +		fprintf(file, ", %s: %d",
   1.314 +			p_section(ns_s_ar, (int)opcode), arcount);
   1.315 +	}
   1.316 +	if ((!statp->pfcode) || (statp->pfcode &
   1.317 +		(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
   1.318 +		putc('\n',file);
   1.319 +	}
   1.320 +	/*
   1.321 +	 * Print the various sections.
   1.322 +	 */
   1.323 +	do_section(statp, &handle, ns_s_qd, RES_PRF_QUES, file);
   1.324 +	do_section(statp, &handle, ns_s_an, RES_PRF_ANS, file);
   1.325 +	do_section(statp, &handle, ns_s_ns, RES_PRF_AUTH, file);
   1.326 +	do_section(statp, &handle, ns_s_ar, RES_PRF_ADD, file);
   1.327 +	if (qdcount == 0 && ancount == 0 &&
   1.328 +	    nscount == 0 && arcount == 0)
   1.329 +		putc('\n', file);
   1.330 +}
   1.331 +
   1.332 +#ifndef MOZILLA_NECKO_EXCLUDE_CODE
   1.333 +const u_char *
   1.334 +p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
   1.335 +	char name[MAXDNAME];
   1.336 +	int n;
   1.337 +
   1.338 +	if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
   1.339 +		return (NULL);
   1.340 +	if (name[0] == '\0')
   1.341 +		putc('.', file);
   1.342 +	else
   1.343 +		fputs(name, file);
   1.344 +	return (cp + n);
   1.345 +}
   1.346 +
   1.347 +const u_char *
   1.348 +p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
   1.349 +	return (p_cdnname(cp, msg, PACKETSZ, file));
   1.350 +}
   1.351 +
   1.352 +/* Return a fully-qualified domain name from a compressed name (with
   1.353 +   length supplied).  */
   1.354 +
   1.355 +const u_char *
   1.356 +p_fqnname(cp, msg, msglen, name, namelen)
   1.357 +	const u_char *cp, *msg;
   1.358 +	int msglen;
   1.359 +	char *name;
   1.360 +	int namelen;
   1.361 +{
   1.362 +	int n, newlen;
   1.363 +
   1.364 +	if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
   1.365 +		return (NULL);
   1.366 +	newlen = strlen(name);
   1.367 +	if (newlen == 0 || name[newlen - 1] != '.') {
   1.368 +		if (newlen + 1 >= namelen)	/* Lack space for final dot */
   1.369 +			return (NULL);
   1.370 +		else
   1.371 +			strcpy(name + newlen, ".");
   1.372 +	}
   1.373 +	return (cp + n);
   1.374 +}
   1.375 +
   1.376 +/* XXX:	the rest of these functions need to become length-limited, too. */
   1.377 +
   1.378 +const u_char *
   1.379 +p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
   1.380 +	char name[MAXDNAME];
   1.381 +	const u_char *n;
   1.382 +
   1.383 +	n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
   1.384 +	if (n == NULL)
   1.385 +		return (NULL);
   1.386 +	fputs(name, file);
   1.387 +	return (n);
   1.388 +}
   1.389 +#endif
   1.390 +
   1.391 +/*
   1.392 + * Names of RR classes and qclasses.  Classes and qclasses are the same, except
   1.393 + * that C_ANY is a qclass but not a class.  (You can ask for records of class
   1.394 + * C_ANY, but you can't have any records of that class in the database.)
   1.395 + */
   1.396 +const struct res_sym __p_class_syms[] = {
   1.397 +	{C_IN,		"IN",		(char *)0},
   1.398 +	{C_CHAOS,	"CH",		(char *)0},
   1.399 +	{C_CHAOS,	"CHAOS",	(char *)0},
   1.400 +	{C_HS,		"HS",		(char *)0},
   1.401 +	{C_HS,		"HESIOD",	(char *)0},
   1.402 +	{C_ANY,		"ANY",		(char *)0},
   1.403 +	{C_NONE,	"NONE",		(char *)0},
   1.404 +	{C_IN, 		(char *)0,	(char *)0}
   1.405 +};
   1.406 +
   1.407 +/*
   1.408 + * Names of message sections.
   1.409 + */
   1.410 +const struct res_sym __p_default_section_syms[] = {
   1.411 +	{ns_s_qd,	"QUERY",	(char *)0},
   1.412 +	{ns_s_an,	"ANSWER",	(char *)0},
   1.413 +	{ns_s_ns,	"AUTHORITY",	(char *)0},
   1.414 +	{ns_s_ar,	"ADDITIONAL",	(char *)0},
   1.415 +	{0,             (char *)0,	(char *)0}
   1.416 +};
   1.417 +
   1.418 +const struct res_sym __p_update_section_syms[] = {
   1.419 +	{S_ZONE,	"ZONE",		(char *)0},
   1.420 +	{S_PREREQ,	"PREREQUISITE",	(char *)0},
   1.421 +	{S_UPDATE,	"UPDATE",	(char *)0},
   1.422 +	{S_ADDT,	"ADDITIONAL",	(char *)0},
   1.423 +	{0,             (char *)0,	(char *)0}
   1.424 +};
   1.425 +
   1.426 +const struct res_sym __p_key_syms[] = {
   1.427 +	{NS_ALG_MD5RSA,		"RSA",		"RSA KEY with MD5 hash"},
   1.428 +	{NS_ALG_DH,		"DH",		"Diffie Hellman"},
   1.429 +	{NS_ALG_DSA,		"DSA",		"Digital Signature Algorithm"},
   1.430 +	{NS_ALG_EXPIRE_ONLY,	"EXPIREONLY",	"No algorithm"},
   1.431 +	{NS_ALG_PRIVATE_OID,	"PRIVATE",	"Algorithm obtained from OID"},
   1.432 +	{0,			NULL,		NULL}
   1.433 +};
   1.434 +
   1.435 +const struct res_sym __p_cert_syms[] = {
   1.436 +	{cert_t_pkix,	"PKIX",		"PKIX (X.509v3) Certificate"},
   1.437 +	{cert_t_spki,	"SPKI",		"SPKI certificate"},
   1.438 +	{cert_t_pgp,	"PGP",		"PGP certificate"},
   1.439 +	{cert_t_url,	"URL",		"URL Private"},
   1.440 +	{cert_t_oid,	"OID",		"OID Private"},
   1.441 +	{0,		NULL,		NULL}
   1.442 +};
   1.443 +
   1.444 +/*
   1.445 + * Names of RR types and qtypes.  Types and qtypes are the same, except
   1.446 + * that T_ANY is a qtype but not a type.  (You can ask for records of type
   1.447 + * T_ANY, but you can't have any records of that type in the database.)
   1.448 + */
   1.449 +const struct res_sym __p_type_syms[] = {
   1.450 +	{ns_t_a,	"A",		"address"},
   1.451 +	{ns_t_ns,	"NS",		"name server"},
   1.452 +	{ns_t_md,	"MD",		"mail destination (deprecated)"},
   1.453 +	{ns_t_mf,	"MF",		"mail forwarder (deprecated)"},
   1.454 +	{ns_t_cname,	"CNAME",	"canonical name"},
   1.455 +	{ns_t_soa,	"SOA",		"start of authority"},
   1.456 +	{ns_t_mb,	"MB",		"mailbox"},
   1.457 +	{ns_t_mg,	"MG",		"mail group member"},
   1.458 +	{ns_t_mr,	"MR",		"mail rename"},
   1.459 +	{ns_t_null,	"NULL",		"null"},
   1.460 +	{ns_t_wks,	"WKS",		"well-known service (deprecated)"},
   1.461 +	{ns_t_ptr,	"PTR",		"domain name pointer"},
   1.462 +	{ns_t_hinfo,	"HINFO",	"host information"},
   1.463 +	{ns_t_minfo,	"MINFO",	"mailbox information"},
   1.464 +	{ns_t_mx,	"MX",		"mail exchanger"},
   1.465 +	{ns_t_txt,	"TXT",		"text"},
   1.466 +	{ns_t_rp,	"RP",		"responsible person"},
   1.467 +	{ns_t_afsdb,	"AFSDB",	"DCE or AFS server"},
   1.468 +	{ns_t_x25,	"X25",		"X25 address"},
   1.469 +	{ns_t_isdn,	"ISDN",		"ISDN address"},
   1.470 +	{ns_t_rt,	"RT",		"router"},
   1.471 +	{ns_t_nsap,	"NSAP",		"nsap address"},
   1.472 +	{ns_t_nsap_ptr,	"NSAP_PTR",	"domain name pointer"},
   1.473 +	{ns_t_sig,	"SIG",		"signature"},
   1.474 +	{ns_t_key,	"KEY",		"key"},
   1.475 +	{ns_t_px,	"PX",		"mapping information"},
   1.476 +	{ns_t_gpos,	"GPOS",		"geographical position (withdrawn)"},
   1.477 +	{ns_t_aaaa,	"AAAA",		"IPv6 address"},
   1.478 +	{ns_t_loc,	"LOC",		"location"},
   1.479 +	{ns_t_nxt,	"NXT",		"next valid name (unimplemented)"},
   1.480 +	{ns_t_eid,	"EID",		"endpoint identifier (unimplemented)"},
   1.481 +	{ns_t_nimloc,	"NIMLOC",	"NIMROD locator (unimplemented)"},
   1.482 +	{ns_t_srv,	"SRV",		"server selection"},
   1.483 +	{ns_t_atma,	"ATMA",		"ATM address (unimplemented)"},
   1.484 +	{ns_t_tkey,	"TKEY",		"tkey"},
   1.485 +	{ns_t_tsig,	"TSIG",		"transaction signature"},
   1.486 +	{ns_t_ixfr,	"IXFR",		"incremental zone transfer"},
   1.487 +	{ns_t_axfr,	"AXFR",		"zone transfer"},
   1.488 +	{ns_t_zxfr,	"ZXFR",		"compressed zone transfer"},
   1.489 +	{ns_t_mailb,	"MAILB",	"mailbox-related data (deprecated)"},
   1.490 +	{ns_t_maila,	"MAILA",	"mail agent (deprecated)"},
   1.491 +	{ns_t_naptr,	"NAPTR",	"URN Naming Authority"},
   1.492 +	{ns_t_kx,	"KX",		"Key Exchange"},
   1.493 +	{ns_t_cert,	"CERT",		"Certificate"},
   1.494 +	{ns_t_a6,	"A6",		"IPv6 Address"},
   1.495 +	{ns_t_dname,	"DNAME",	"dname"},
   1.496 +	{ns_t_sink,	"SINK",		"Kitchen Sink (experimental)"},
   1.497 +	{ns_t_opt,	"OPT",		"EDNS Options"},
   1.498 +	{ns_t_any,	"ANY",		"\"any\""},
   1.499 +	{0, 		NULL,		NULL}
   1.500 +};
   1.501 +
   1.502 +/*
   1.503 + * Names of DNS rcodes.
   1.504 + */
   1.505 +const struct res_sym __p_rcode_syms[] = {
   1.506 +	{ns_r_noerror,	"NOERROR",		"no error"},
   1.507 +	{ns_r_formerr,	"FORMERR",		"format error"},
   1.508 +	{ns_r_servfail,	"SERVFAIL",		"server failed"},
   1.509 +	{ns_r_nxdomain,	"NXDOMAIN",		"no such domain name"},
   1.510 +	{ns_r_notimpl,	"NOTIMP",		"not implemented"},
   1.511 +	{ns_r_refused,	"REFUSED",		"refused"},
   1.512 +	{ns_r_yxdomain,	"YXDOMAIN",		"domain name exists"},
   1.513 +	{ns_r_yxrrset,	"YXRRSET",		"rrset exists"},
   1.514 +	{ns_r_nxrrset,	"NXRRSET",		"rrset doesn't exist"},
   1.515 +	{ns_r_notauth,	"NOTAUTH",		"not authoritative"},
   1.516 +	{ns_r_notzone,	"NOTZONE",		"Not in zone"},
   1.517 +	{ns_r_max,	"",			""},
   1.518 +	{ns_r_badsig,	"BADSIG",		"bad signature"},
   1.519 +	{ns_r_badkey,	"BADKEY",		"bad key"},
   1.520 +	{ns_r_badtime,	"BADTIME",		"bad time"},
   1.521 +	{0, 		NULL,			NULL}
   1.522 +};
   1.523 +
   1.524 +int
   1.525 +sym_ston(const struct res_sym *syms, const char *name, int *success) {
   1.526 +	for (; syms->name != 0; syms++) {
   1.527 +		if (strcasecmp (name, syms->name) == 0) {
   1.528 +			if (success)
   1.529 +				*success = 1;
   1.530 +			return (syms->number);
   1.531 +		}
   1.532 +	}
   1.533 +	if (success)
   1.534 +		*success = 0;
   1.535 +	return (syms->number);		/* The default value. */
   1.536 +}
   1.537 +
   1.538 +const char *
   1.539 +sym_ntos(const struct res_sym *syms, int number, int *success) {
   1.540 +	static char unname[20];
   1.541 +
   1.542 +	for (; syms->name != 0; syms++) {
   1.543 +		if (number == syms->number) {
   1.544 +			if (success)
   1.545 +				*success = 1;
   1.546 +			return (syms->name);
   1.547 +		}
   1.548 +	}
   1.549 +
   1.550 +	sprintf(unname, "%d", number);		/* XXX nonreentrant */
   1.551 +	if (success)
   1.552 +		*success = 0;
   1.553 +	return (unname);
   1.554 +}
   1.555 +
   1.556 +const char *
   1.557 +sym_ntop(const struct res_sym *syms, int number, int *success) {
   1.558 +	static char unname[20];
   1.559 +
   1.560 +	for (; syms->name != 0; syms++) {
   1.561 +		if (number == syms->number) {
   1.562 +			if (success)
   1.563 +				*success = 1;
   1.564 +			return (syms->humanname);
   1.565 +		}
   1.566 +	}
   1.567 +	sprintf(unname, "%d", number);		/* XXX nonreentrant */
   1.568 +	if (success)
   1.569 +		*success = 0;
   1.570 +	return (unname);
   1.571 +}
   1.572 +
   1.573 +/*
   1.574 + * Return a string for the type.
   1.575 + */
   1.576 +const char *
   1.577 +p_type(int type) {
   1.578 +	int success;
   1.579 +	const char *result;
   1.580 +	static char typebuf[20];
   1.581 +
   1.582 +	result = sym_ntos(__p_type_syms, type, &success);
   1.583 +	if (success)
   1.584 +		return (result);
   1.585 +	if (type < 0 || type > 0xffff)
   1.586 +		return ("BADTYPE");
   1.587 +	sprintf(typebuf, "TYPE%d", type);
   1.588 +	return (typebuf);
   1.589 +}
   1.590 +
   1.591 +/*
   1.592 + * Return a string for the type.
   1.593 + */
   1.594 +const char *
   1.595 +p_section(int section, int opcode) {
   1.596 +	const struct res_sym *symbols;
   1.597 +
   1.598 +	switch (opcode) {
   1.599 +	case ns_o_update:
   1.600 +		symbols = __p_update_section_syms;
   1.601 +		break;
   1.602 +	default:
   1.603 +		symbols = __p_default_section_syms;
   1.604 +		break;
   1.605 +	}
   1.606 +	return (sym_ntos(symbols, section, (int *)0));
   1.607 +}
   1.608 +
   1.609 +/*
   1.610 + * Return a mnemonic for class.
   1.611 + */
   1.612 +const char *
   1.613 +p_class(int class) {
   1.614 +	int success;
   1.615 +	const char *result;
   1.616 +	static char classbuf[20];
   1.617 +
   1.618 +	result = sym_ntos(__p_class_syms, class, &success);
   1.619 +	if (success)
   1.620 +		return (result);
   1.621 +	if (class < 0 || class > 0xffff)
   1.622 +		return ("BADCLASS");
   1.623 +	sprintf(classbuf, "CLASS%d", class);
   1.624 +	return (classbuf);
   1.625 +}
   1.626 +
   1.627 +/*
   1.628 + * Return a mnemonic for an option
   1.629 + */
   1.630 +const char *
   1.631 +p_option(u_long option) {
   1.632 +	static char nbuf[40];
   1.633 +
   1.634 +	switch (option) {
   1.635 +	case RES_INIT:		return "init";
   1.636 +	case RES_DEBUG:		return "debug";
   1.637 +	case RES_AAONLY:	return "aaonly(unimpl)";
   1.638 +	case RES_USEVC:		return "usevc";
   1.639 +	case RES_PRIMARY:	return "primry(unimpl)";
   1.640 +	case RES_IGNTC:		return "igntc";
   1.641 +	case RES_RECURSE:	return "recurs";
   1.642 +	case RES_DEFNAMES:	return "defnam";
   1.643 +	case RES_STAYOPEN:	return "styopn";
   1.644 +	case RES_DNSRCH:	return "dnsrch";
   1.645 +	case RES_INSECURE1:	return "insecure1";
   1.646 +	case RES_INSECURE2:	return "insecure2";
   1.647 +	case RES_NOALIASES:	return "noaliases";
   1.648 +	case RES_USE_INET6:	return "inet6";
   1.649 +#ifdef RES_USE_EDNS0	/* KAME extension */
   1.650 +	case RES_USE_EDNS0:	return "edns0";
   1.651 +#endif
   1.652 +#ifdef RES_USE_DNAME
   1.653 +	case RES_USE_DNAME:	return "dname";
   1.654 +#endif
   1.655 +#ifdef RES_USE_DNSSEC
   1.656 +	case RES_USE_DNSSEC:	return "dnssec";
   1.657 +#endif
   1.658 +#ifdef RES_NOTLDQUERY
   1.659 +	case RES_NOTLDQUERY:	return "no-tld-query";
   1.660 +#endif
   1.661 +#ifdef RES_NO_NIBBLE2
   1.662 +	case RES_NO_NIBBLE2:	return "no-nibble2";
   1.663 +#endif
   1.664 +				/* XXX nonreentrant */
   1.665 +	default:		sprintf(nbuf, "?0x%lx?", (u_long)option);
   1.666 +				return (nbuf);
   1.667 +	}
   1.668 +}
   1.669 +
   1.670 +#ifndef MOZILLA_NECKO_EXCLUDE_CODE
   1.671 +/*
   1.672 + * Return a mnemonic for a time to live.
   1.673 + */
   1.674 +const char *
   1.675 +p_time(u_int32_t value) {
   1.676 +	static char nbuf[40];		/* XXX nonreentrant */
   1.677 +
   1.678 +	if (ns_format_ttl((u_long)value, nbuf, sizeof nbuf) < 0)
   1.679 +		sprintf(nbuf, "%u", value);
   1.680 +	return (nbuf);
   1.681 +}
   1.682 +#endif
   1.683 +
   1.684 +/*
   1.685 + * Return a string for the rcode.
   1.686 + */
   1.687 +const char *
   1.688 +p_rcode(int rcode) {
   1.689 +	return (sym_ntos(__p_rcode_syms, rcode, (int *)0));
   1.690 +}
   1.691 +
   1.692 +#ifndef MOZILLA_NECKO_EXCLUDE_CODE
   1.693 +/*
   1.694 + * Return a string for a res_sockaddr_union.
   1.695 + */
   1.696 +const char *
   1.697 +p_sockun(union res_sockaddr_union u, char *buf, size_t size) {
   1.698 +	char ret[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:123.123.123.123"];
   1.699 +
   1.700 +	switch (u.sin.sin_family) {
   1.701 +	case AF_INET:
   1.702 +		inet_ntop(AF_INET, &u.sin.sin_addr, ret, sizeof ret);
   1.703 +		break;
   1.704 +#ifdef HAS_INET6_STRUCTS
   1.705 +	case AF_INET6:
   1.706 +		inet_ntop(AF_INET6, &u.sin6.sin6_addr, ret, sizeof ret);
   1.707 +		break;
   1.708 +#endif
   1.709 +	default:
   1.710 +		sprintf(ret, "[af%d]", u.sin.sin_family);
   1.711 +		break;
   1.712 +	}
   1.713 +	if (size > 0U) {
   1.714 +		strncpy(buf, ret, size - 1);
   1.715 +		buf[size - 1] = '0';
   1.716 +	}
   1.717 +	return (buf);
   1.718 +}
   1.719 +#endif
   1.720 +
   1.721 +/*
   1.722 + * routines to convert between on-the-wire RR format and zone file format.
   1.723 + * Does not contain conversion to/from decimal degrees; divide or multiply
   1.724 + * by 60*60*1000 for that.
   1.725 + */
   1.726 +
   1.727 +static const unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
   1.728 +				      1000000,10000000,100000000,1000000000};
   1.729 +
   1.730 +/* takes an XeY precision/size value, returns a string representation. */
   1.731 +static const char *
   1.732 +precsize_ntoa(prec)
   1.733 +	u_int32_t prec;
   1.734 +{
   1.735 +	static char retbuf[sizeof "90000000.00"];	/* XXX nonreentrant */
   1.736 +	unsigned long val;
   1.737 +	int mantissa, exponent;
   1.738 +
   1.739 +	mantissa = (int)((prec >> 4) & 0x0f) % 10;
   1.740 +	exponent = (int)((prec >> 0) & 0x0f) % 10;
   1.741 +
   1.742 +	val = mantissa * poweroften[exponent];
   1.743 +
   1.744 +	(void) sprintf(retbuf, "%lu.%.2lu", val/100, val%100);
   1.745 +	return (retbuf);
   1.746 +}
   1.747 +
   1.748 +#ifndef MOZILLA_NECKO_EXCLUDE_CODE
   1.749 +/* converts ascii size/precision X * 10**Y(cm) to 0xXY.  moves pointer. */
   1.750 +static u_int8_t
   1.751 +precsize_aton(const char **strptr) {
   1.752 +	unsigned int mval = 0, cmval = 0;
   1.753 +	u_int8_t retval = 0;
   1.754 +	const char *cp;
   1.755 +	int exponent;
   1.756 +	int mantissa;
   1.757 +
   1.758 +	cp = *strptr;
   1.759 +
   1.760 +	while (isdigit((unsigned char)*cp))
   1.761 +		mval = mval * 10 + (*cp++ - '0');
   1.762 +
   1.763 +	if (*cp == '.') {		/* centimeters */
   1.764 +		cp++;
   1.765 +		if (isdigit((unsigned char)*cp)) {
   1.766 +			cmval = (*cp++ - '0') * 10;
   1.767 +			if (isdigit((unsigned char)*cp)) {
   1.768 +				cmval += (*cp++ - '0');
   1.769 +			}
   1.770 +		}
   1.771 +	}
   1.772 +	cmval = (mval * 100) + cmval;
   1.773 +
   1.774 +	for (exponent = 0; exponent < 9; exponent++)
   1.775 +		if (cmval < poweroften[exponent+1])
   1.776 +			break;
   1.777 +
   1.778 +	mantissa = cmval / poweroften[exponent];
   1.779 +	if (mantissa > 9)
   1.780 +		mantissa = 9;
   1.781 +
   1.782 +	retval = (mantissa << 4) | exponent;
   1.783 +
   1.784 +	*strptr = cp;
   1.785 +
   1.786 +	return (retval);
   1.787 +}
   1.788 +
   1.789 +/* converts ascii lat/lon to unsigned encoded 32-bit number.  moves pointer. */
   1.790 +static u_int32_t
   1.791 +latlon2ul(const char **latlonstrptr, int *which) {
   1.792 +	const char *cp;
   1.793 +	u_int32_t retval;
   1.794 +	int deg = 0, min = 0, secs = 0, secsfrac = 0;
   1.795 +
   1.796 +	cp = *latlonstrptr;
   1.797 +
   1.798 +	while (isdigit((unsigned char)*cp))
   1.799 +		deg = deg * 10 + (*cp++ - '0');
   1.800 +
   1.801 +	while (isspace((unsigned char)*cp))
   1.802 +		cp++;
   1.803 +
   1.804 +	if (!(isdigit((unsigned char)*cp)))
   1.805 +		goto fndhemi;
   1.806 +
   1.807 +	while (isdigit((unsigned char)*cp))
   1.808 +		min = min * 10 + (*cp++ - '0');
   1.809 +
   1.810 +	while (isspace((unsigned char)*cp))
   1.811 +		cp++;
   1.812 +
   1.813 +	if (!(isdigit((unsigned char)*cp)))
   1.814 +		goto fndhemi;
   1.815 +
   1.816 +	while (isdigit((unsigned char)*cp))
   1.817 +		secs = secs * 10 + (*cp++ - '0');
   1.818 +
   1.819 +	if (*cp == '.') {		/* decimal seconds */
   1.820 +		cp++;
   1.821 +		if (isdigit((unsigned char)*cp)) {
   1.822 +			secsfrac = (*cp++ - '0') * 100;
   1.823 +			if (isdigit((unsigned char)*cp)) {
   1.824 +				secsfrac += (*cp++ - '0') * 10;
   1.825 +				if (isdigit((unsigned char)*cp)) {
   1.826 +					secsfrac += (*cp++ - '0');
   1.827 +				}
   1.828 +			}
   1.829 +		}
   1.830 +	}
   1.831 +
   1.832 +	while (!isspace((unsigned char)*cp))	/* if any trailing garbage */
   1.833 +		cp++;
   1.834 +
   1.835 +	while (isspace((unsigned char)*cp))
   1.836 +		cp++;
   1.837 +
   1.838 + fndhemi:
   1.839 +	switch (*cp) {
   1.840 +	case 'N': case 'n':
   1.841 +	case 'E': case 'e':
   1.842 +		retval = ((unsigned)1<<31)
   1.843 +			+ (((((deg * 60) + min) * 60) + secs) * 1000)
   1.844 +			+ secsfrac;
   1.845 +		break;
   1.846 +	case 'S': case 's':
   1.847 +	case 'W': case 'w':
   1.848 +		retval = ((unsigned)1<<31)
   1.849 +			- (((((deg * 60) + min) * 60) + secs) * 1000)
   1.850 +			- secsfrac;
   1.851 +		break;
   1.852 +	default:
   1.853 +		retval = 0;	/* invalid value -- indicates error */
   1.854 +		break;
   1.855 +	}
   1.856 +
   1.857 +	switch (*cp) {
   1.858 +	case 'N': case 'n':
   1.859 +	case 'S': case 's':
   1.860 +		*which = 1;	/* latitude */
   1.861 +		break;
   1.862 +	case 'E': case 'e':
   1.863 +	case 'W': case 'w':
   1.864 +		*which = 2;	/* longitude */
   1.865 +		break;
   1.866 +	default:
   1.867 +		*which = 0;	/* error */
   1.868 +		break;
   1.869 +	}
   1.870 +
   1.871 +	cp++;			/* skip the hemisphere */
   1.872 +
   1.873 +	while (!isspace((unsigned char)*cp))	/* if any trailing garbage */
   1.874 +		cp++;
   1.875 +
   1.876 +	while (isspace((unsigned char)*cp))	/* move to next field */
   1.877 +		cp++;
   1.878 +
   1.879 +	*latlonstrptr = cp;
   1.880 +
   1.881 +	return (retval);
   1.882 +}
   1.883 +
   1.884 +/* converts a zone file representation in a string to an RDATA on-the-wire
   1.885 + * representation. */
   1.886 +int
   1.887 +loc_aton(ascii, binary)
   1.888 +	const char *ascii;
   1.889 +	u_char *binary;
   1.890 +{
   1.891 +	const char *cp, *maxcp;
   1.892 +	u_char *bcp;
   1.893 +
   1.894 +	u_int32_t latit = 0, longit = 0, alt = 0;
   1.895 +	u_int32_t lltemp1 = 0, lltemp2 = 0;
   1.896 +	int altmeters = 0, altfrac = 0, altsign = 1;
   1.897 +	u_int8_t hp = 0x16;	/* default = 1e6 cm = 10000.00m = 10km */
   1.898 +	u_int8_t vp = 0x13;	/* default = 1e3 cm = 10.00m */
   1.899 +	u_int8_t siz = 0x12;	/* default = 1e2 cm = 1.00m */
   1.900 +	int which1 = 0, which2 = 0;
   1.901 +
   1.902 +	cp = ascii;
   1.903 +	maxcp = cp + strlen(ascii);
   1.904 +
   1.905 +	lltemp1 = latlon2ul(&cp, &which1);
   1.906 +
   1.907 +	lltemp2 = latlon2ul(&cp, &which2);
   1.908 +
   1.909 +	switch (which1 + which2) {
   1.910 +	case 3:			/* 1 + 2, the only valid combination */
   1.911 +		if ((which1 == 1) && (which2 == 2)) { /* normal case */
   1.912 +			latit = lltemp1;
   1.913 +			longit = lltemp2;
   1.914 +		} else if ((which1 == 2) && (which2 == 1)) { /* reversed */
   1.915 +			longit = lltemp1;
   1.916 +			latit = lltemp2;
   1.917 +		} else {	/* some kind of brokenness */
   1.918 +			return (0);
   1.919 +		}
   1.920 +		break;
   1.921 +	default:		/* we didn't get one of each */
   1.922 +		return (0);
   1.923 +	}
   1.924 +
   1.925 +	/* altitude */
   1.926 +	if (*cp == '-') {
   1.927 +		altsign = -1;
   1.928 +		cp++;
   1.929 +	}
   1.930 +
   1.931 +	if (*cp == '+')
   1.932 +		cp++;
   1.933 +
   1.934 +	while (isdigit((unsigned char)*cp))
   1.935 +		altmeters = altmeters * 10 + (*cp++ - '0');
   1.936 +
   1.937 +	if (*cp == '.') {		/* decimal meters */
   1.938 +		cp++;
   1.939 +		if (isdigit((unsigned char)*cp)) {
   1.940 +			altfrac = (*cp++ - '0') * 10;
   1.941 +			if (isdigit((unsigned char)*cp)) {
   1.942 +				altfrac += (*cp++ - '0');
   1.943 +			}
   1.944 +		}
   1.945 +	}
   1.946 +
   1.947 +	alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
   1.948 +
   1.949 +	while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */
   1.950 +		cp++;
   1.951 +
   1.952 +	while (isspace((unsigned char)*cp) && (cp < maxcp))
   1.953 +		cp++;
   1.954 +
   1.955 +	if (cp >= maxcp)
   1.956 +		goto defaults;
   1.957 +
   1.958 +	siz = precsize_aton(&cp);
   1.959 +
   1.960 +	while (!isspace((unsigned char)*cp) && (cp < maxcp))	/* if trailing garbage or m */
   1.961 +		cp++;
   1.962 +
   1.963 +	while (isspace((unsigned char)*cp) && (cp < maxcp))
   1.964 +		cp++;
   1.965 +
   1.966 +	if (cp >= maxcp)
   1.967 +		goto defaults;
   1.968 +
   1.969 +	hp = precsize_aton(&cp);
   1.970 +
   1.971 +	while (!isspace((unsigned char)*cp) && (cp < maxcp))	/* if trailing garbage or m */
   1.972 +		cp++;
   1.973 +
   1.974 +	while (isspace((unsigned char)*cp) && (cp < maxcp))
   1.975 +		cp++;
   1.976 +
   1.977 +	if (cp >= maxcp)
   1.978 +		goto defaults;
   1.979 +
   1.980 +	vp = precsize_aton(&cp);
   1.981 +
   1.982 + defaults:
   1.983 +
   1.984 +	bcp = binary;
   1.985 +	*bcp++ = (u_int8_t) 0;	/* version byte */
   1.986 +	*bcp++ = siz;
   1.987 +	*bcp++ = hp;
   1.988 +	*bcp++ = vp;
   1.989 +	PUTLONG(latit,bcp);
   1.990 +	PUTLONG(longit,bcp);
   1.991 +	PUTLONG(alt,bcp);
   1.992 +
   1.993 +	return (16);		/* size of RR in octets */
   1.994 +}
   1.995 +#endif
   1.996 +
   1.997 +/* takes an on-the-wire LOC RR and formats it in a human readable format. */
   1.998 +const char *
   1.999 +loc_ntoa(binary, ascii)
  1.1000 +	const u_char *binary;
  1.1001 +	char *ascii;
  1.1002 +{
  1.1003 +	static const char *error = "?";
  1.1004 +	static char tmpbuf[sizeof
  1.1005 +"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
  1.1006 +	const u_char *cp = binary;
  1.1007 +
  1.1008 +	int latdeg, latmin, latsec, latsecfrac;
  1.1009 +	int longdeg, longmin, longsec, longsecfrac;
  1.1010 +	char northsouth, eastwest;
  1.1011 +	const char *altsign;
  1.1012 +	int altmeters, altfrac;
  1.1013 +
  1.1014 +	const u_int32_t referencealt = 100000 * 100;
  1.1015 +
  1.1016 +	int32_t latval, longval, altval;
  1.1017 +	u_int32_t templ;
  1.1018 +	u_int8_t sizeval, hpval, vpval, versionval;
  1.1019 +
  1.1020 +	char *sizestr, *hpstr, *vpstr;
  1.1021 +
  1.1022 +	versionval = *cp++;
  1.1023 +
  1.1024 +	if (ascii == NULL)
  1.1025 +		ascii = tmpbuf;
  1.1026 +
  1.1027 +	if (versionval) {
  1.1028 +		(void) sprintf(ascii, "; error: unknown LOC RR version");
  1.1029 +		return (ascii);
  1.1030 +	}
  1.1031 +
  1.1032 +	sizeval = *cp++;
  1.1033 +
  1.1034 +	hpval = *cp++;
  1.1035 +	vpval = *cp++;
  1.1036 +
  1.1037 +	GETLONG(templ, cp);
  1.1038 +	latval = (templ - ((unsigned)1<<31));
  1.1039 +
  1.1040 +	GETLONG(templ, cp);
  1.1041 +	longval = (templ - ((unsigned)1<<31));
  1.1042 +
  1.1043 +	GETLONG(templ, cp);
  1.1044 +	if (templ < referencealt) { /* below WGS 84 spheroid */
  1.1045 +		altval = referencealt - templ;
  1.1046 +		altsign = "-";
  1.1047 +	} else {
  1.1048 +		altval = templ - referencealt;
  1.1049 +		altsign = "";
  1.1050 +	}
  1.1051 +
  1.1052 +	if (latval < 0) {
  1.1053 +		northsouth = 'S';
  1.1054 +		latval = -latval;
  1.1055 +	} else
  1.1056 +		northsouth = 'N';
  1.1057 +
  1.1058 +	latsecfrac = latval % 1000;
  1.1059 +	latval = latval / 1000;
  1.1060 +	latsec = latval % 60;
  1.1061 +	latval = latval / 60;
  1.1062 +	latmin = latval % 60;
  1.1063 +	latval = latval / 60;
  1.1064 +	latdeg = latval;
  1.1065 +
  1.1066 +	if (longval < 0) {
  1.1067 +		eastwest = 'W';
  1.1068 +		longval = -longval;
  1.1069 +	} else
  1.1070 +		eastwest = 'E';
  1.1071 +
  1.1072 +	longsecfrac = longval % 1000;
  1.1073 +	longval = longval / 1000;
  1.1074 +	longsec = longval % 60;
  1.1075 +	longval = longval / 60;
  1.1076 +	longmin = longval % 60;
  1.1077 +	longval = longval / 60;
  1.1078 +	longdeg = longval;
  1.1079 +
  1.1080 +	altfrac = altval % 100;
  1.1081 +	altmeters = (altval / 100);
  1.1082 +
  1.1083 +	sizestr = strdup(precsize_ntoa((u_int32_t)sizeval));
  1.1084 +	hpstr = strdup(precsize_ntoa((u_int32_t)hpval));
  1.1085 +	vpstr = strdup(precsize_ntoa((u_int32_t)vpval));
  1.1086 +
  1.1087 +	sprintf(ascii,
  1.1088 +	    "%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm",
  1.1089 +		latdeg, latmin, latsec, latsecfrac, northsouth,
  1.1090 +		longdeg, longmin, longsec, longsecfrac, eastwest,
  1.1091 +		altsign, altmeters, altfrac,
  1.1092 +		(sizestr != NULL) ? sizestr : error,
  1.1093 +		(hpstr != NULL) ? hpstr : error,
  1.1094 +		(vpstr != NULL) ? vpstr : error);
  1.1095 +
  1.1096 +	if (sizestr != NULL)
  1.1097 +		free(sizestr);
  1.1098 +	if (hpstr != NULL)
  1.1099 +		free(hpstr);
  1.1100 +	if (vpstr != NULL)
  1.1101 +		free(vpstr);
  1.1102 +
  1.1103 +	return (ascii);
  1.1104 +}
  1.1105 +
  1.1106 +
  1.1107 +/* Return the number of DNS hierarchy levels in the name. */
  1.1108 +int
  1.1109 +dn_count_labels(const char *name) {
  1.1110 +	int i, len, count;
  1.1111 +
  1.1112 +	len = strlen(name);
  1.1113 +	for (i = 0, count = 0; i < len; i++) {
  1.1114 +		/* XXX need to check for \. or use named's nlabels(). */
  1.1115 +		if (name[i] == '.')
  1.1116 +			count++;
  1.1117 +	}
  1.1118 +
  1.1119 +	/* don't count initial wildcard */
  1.1120 +	if (name[0] == '*')
  1.1121 +		if (count)
  1.1122 +			count--;
  1.1123 +
  1.1124 +	/* don't count the null label for root. */
  1.1125 +	/* if terminating '.' not found, must adjust */
  1.1126 +	/* count to include last label */
  1.1127 +	if (len > 0 && name[len-1] != '.')
  1.1128 +		count++;
  1.1129 +	return (count);
  1.1130 +}
  1.1131 +
  1.1132 +
  1.1133 +/*
  1.1134 + * Make dates expressed in seconds-since-Jan-1-1970 easy to read.
  1.1135 + * SIG records are required to be printed like this, by the Secure DNS RFC.
  1.1136 + */
  1.1137 +char *
  1.1138 +p_secstodate (u_long secs) {
  1.1139 +	/* XXX nonreentrant */
  1.1140 +	static char output[15];		/* YYYYMMDDHHMMSS and null */
  1.1141 +	time_t myclock = secs;
  1.1142 +	struct tm *mytime;
  1.1143 +#ifdef HAVE_TIME_R
  1.1144 +	struct tm res;
  1.1145 +
  1.1146 +	mytime = gmtime_r(&myclock, &res);
  1.1147 +#else
  1.1148 +	mytime = gmtime(&myclock);
  1.1149 +#endif
  1.1150 +	mytime->tm_year += 1900;
  1.1151 +	mytime->tm_mon += 1;
  1.1152 +	sprintf(output, "%04d%02d%02d%02d%02d%02d",
  1.1153 +		mytime->tm_year, mytime->tm_mon, mytime->tm_mday,
  1.1154 +		mytime->tm_hour, mytime->tm_min, mytime->tm_sec);
  1.1155 +	return (output);
  1.1156 +}
  1.1157 +
  1.1158 +#ifndef MOZILLA_NECKO_EXCLUDE_CODE
  1.1159 +u_int16_t
  1.1160 +res_nametoclass(const char *buf, int *successp) {
  1.1161 +	unsigned long result;
  1.1162 +	char *endptr;
  1.1163 +	int success;
  1.1164 +
  1.1165 +	result = sym_ston(__p_class_syms, buf, &success);
  1.1166 +	if (success)
  1.1167 +		goto done;
  1.1168 +
  1.1169 +	if (strncasecmp(buf, "CLASS", 5) != 0 ||
  1.1170 +	    !isdigit((unsigned char)buf[5]))
  1.1171 +		goto done;
  1.1172 +	errno = 0;
  1.1173 +	result = strtoul(buf + 5, &endptr, 10);
  1.1174 +	if (errno == 0 && *endptr == '\0' && result <= 0xffffU)
  1.1175 +		success = 1;
  1.1176 + done:
  1.1177 +	if (successp)
  1.1178 +		*successp = success;
  1.1179 +	return (u_int16_t)(result);
  1.1180 +}
  1.1181 +
  1.1182 +u_int16_t
  1.1183 +res_nametotype(const char *buf, int *successp) {
  1.1184 +	unsigned long result;
  1.1185 +	char *endptr;
  1.1186 +	int success;
  1.1187 +
  1.1188 +	result = sym_ston(__p_type_syms, buf, &success);
  1.1189 +	if (success)
  1.1190 +		goto done;
  1.1191 +
  1.1192 +	if (strncasecmp(buf, "type", 4) != 0 ||
  1.1193 +	    !isdigit((unsigned char)buf[4]))
  1.1194 +		goto done;
  1.1195 +	errno = 0;
  1.1196 +	result = strtoul(buf + 4, &endptr, 10);
  1.1197 +	if (errno == 0 && *endptr == '\0' && result <= 0xffffU)
  1.1198 +		success = 1;
  1.1199 + done:
  1.1200 +	if (successp)
  1.1201 +		*successp = success;
  1.1202 +	return (u_int16_t)(result);
  1.1203 +}
  1.1204 +#endif

mercurial