diff options
Diffstat (limited to 'resolv/res_debug.c')
-rw-r--r-- | resolv/res_debug.c | 1234 |
1 files changed, 355 insertions, 879 deletions
diff --git a/resolv/res_debug.c b/resolv/res_debug.c index dac878d..2df1c5b 100644 --- a/resolv/res_debug.c +++ b/resolv/res_debug.c @@ -1,7 +1,5 @@ /* - * ++Copyright++ 1985, 1990, 1993 - * - - * Copyright (c) 1985, 1990, 1993 + * Copyright (c) 1985 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,7 +25,9 @@ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - + */ + +/* * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any @@ -45,7 +45,9 @@ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. - * - + */ + +/* * Portions Copyright (c) 1995 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants @@ -68,202 +70,121 @@ * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. - * --Copyright-- + */ + +/* + * Portions Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id$"; +static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; +static const char rcsid[] = "$Id$"; #endif /* LIBC_SCCS and not lint */ -#include <sys/param.h> #include <sys/types.h> +#include <sys/param.h> #include <sys/socket.h> + #include <netinet/in.h> #include <arpa/inet.h> #include <arpa/nameser.h> #include <ctype.h> +#include <errno.h> +#include <math.h> #include <netdb.h> #include <resolv.h> #include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <time.h> -#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6) -# include <stdlib.h> -# include <string.h> +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) #else -# include "../conf/portability.h" -#endif - -#if defined(USE_OPTIONS_H) -# include "../conf/options.h" +# define SPRINTF(x) sprintf x #endif extern const char *_res_opcodes[]; -extern const char *_res_resultcodes[]; +extern const char *_res_sectioncodes[]; -/* XXX: we should use getservbyport() instead. */ -static const char * -dewks(wks) - int wks; -{ - static char nbuf[20]; - - switch (wks) { - case 5: return "rje"; - case 7: return "echo"; - case 9: return "discard"; - case 11: return "systat"; - case 13: return "daytime"; - case 15: return "netstat"; - case 17: return "qotd"; - case 19: return "chargen"; - case 20: return "ftp-data"; - case 21: return "ftp"; - case 23: return "telnet"; - case 25: return "smtp"; - case 37: return "time"; - case 39: return "rlp"; - case 42: return "name"; - case 43: return "whois"; - case 53: return "domain"; - case 57: return "apts"; - case 59: return "apfs"; - case 67: return "bootps"; - case 68: return "bootpc"; - case 69: return "tftp"; - case 77: return "rje"; - case 79: return "finger"; - case 87: return "link"; - case 95: return "supdup"; - case 100: return "newacct"; - case 101: return "hostnames"; - case 102: return "iso-tsap"; - case 103: return "x400"; - case 104: return "x400-snd"; - case 105: return "csnet-ns"; - case 109: return "pop-2"; - case 111: return "sunrpc"; - case 113: return "auth"; - case 115: return "sftp"; - case 117: return "uucp-path"; - case 119: return "nntp"; - case 121: return "erpc"; - case 123: return "ntp"; - case 133: return "statsrv"; - case 136: return "profile"; - case 144: return "NeWS"; - case 161: return "snmp"; - case 162: return "snmp-trap"; - case 170: return "print-srv"; - default: (void) sprintf(nbuf, "%d", wks); return (nbuf); - } -} +/* + * Print the current options. + */ +void +fp_resstat(const res_state statp, FILE *file) { + u_long mask; -/* XXX: we should use getprotobynumber() instead. */ -static const char * -deproto(protonum) - int protonum; -{ - static char nbuf[20]; - - switch (protonum) { - case 1: return "icmp"; - case 2: return "igmp"; - case 3: return "ggp"; - case 5: return "st"; - case 6: return "tcp"; - case 7: return "ucl"; - case 8: return "egp"; - case 9: return "igp"; - case 11: return "nvp-II"; - case 12: return "pup"; - case 16: return "chaos"; - case 17: return "udp"; - default: (void) sprintf(nbuf, "%d", protonum); return (nbuf); - } + fprintf(file, ";; res options:"); + for (mask = 1; mask != 0; mask <<= 1) + if (statp->options & mask) + fprintf(file, " %s", p_option(mask)); + putc('\n', file); } -static const u_char * -do_rrset(msg, len, cp, cnt, pflag, file, hs) - int cnt, pflag, len; - const u_char *cp, *msg; - const char *hs; - FILE *file; +static void +do_section(const res_state statp, + ns_msg *handle, ns_sect section, + int pflag, FILE *file) { - int n; - int sflag; + int n, sflag, rrnum; + char buf[2048]; /* XXX need to malloc */ + ns_opcode opcode; + ns_rr rr; /* * Print answer records. */ - sflag = (_res.pfcode & pflag); - if ((n = ntohs(cnt))) { - if ((!_res.pfcode) || - ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) - fprintf(file, hs); - while (--n >= 0) { - if ((!_res.pfcode) || sflag) { - cp = p_rr(cp, msg, file); - } else { - unsigned int dlen; - cp += __dn_skipname(cp, cp + MAXCDNAME); - cp += INT16SZ; - cp += INT16SZ; - cp += INT32SZ; - dlen = _getshort((u_char*)cp); - cp += INT16SZ; - cp += dlen; + sflag = (statp->pfcode & pflag); + if (statp->pfcode && !sflag) + return; + + opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode); + rrnum = 0; + for (;;) { + if (ns_parserr(handle, section, rrnum, &rr)) { + if (errno != ENODEV) + fprintf(file, ";; ns_parserr: %s\n", + strerror(errno)); + else if (rrnum > 0 && sflag != 0 && + (statp->pfcode & RES_PRF_HEAD1)) + putc('\n', file); + return; + } + if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1)) + fprintf(file, ";; %s SECTION:\n", + p_section(section, opcode)); + if (section == ns_s_qd) + fprintf(file, ";;\t%s, type = %s, class = %s\n", + ns_rr_name(rr), + p_type(ns_rr_type(rr)), + p_class(ns_rr_class(rr))); + else { + n = ns_sprintrr(handle, &rr, NULL, NULL, + buf, sizeof buf); + if (n < 0) { + fprintf(file, ";; ns_sprintrr: %s\n", + strerror(errno)); + return; } - if ((cp - msg) > len) - return (NULL); + fputs(buf, file); + fputc('\n', file); } - if ((!_res.pfcode) || - ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) - putc('\n', file); + rrnum++; } - return (cp); -} - -void -__p_query(msg) - const u_char *msg; -{ - __fp_query(msg, stdout); -} - -#ifdef ultrix -#undef p_query -/* ultrix 4.0's packaging has some icky packaging. alias for it here. - * there is more junk of this kind over in res_comp.c. - */ -void -p_query(msg) - const u_char *msg; -{ - __p_query(msg); -} -#endif - -/* - * Print the current options. - * This is intended to be primarily a debugging routine. - */ -void -__fp_resstat(statp, file) - struct __res_state *statp; - FILE *file; -{ - register u_long mask; - - fprintf(file, ";; res options:"); - if (!statp) - statp = &_res; - for (mask = 1; mask != 0; mask <<= 1) - if (statp->options & mask) - fprintf(file, " %s", p_option(mask)); - putc('\n', file); } /* @@ -271,147 +192,79 @@ __fp_resstat(statp, file) * This is intended to be primarily a debugging routine. */ void -__fp_nquery(msg, len, file) - const u_char *msg; - int len; - FILE *file; -{ - register const u_char *cp, *endMark; - register const HEADER *hp; - register int n; +res_pquery(const res_state statp, const u_char *msg, int len, FILE *file) { + ns_msg handle; + int qdcount, ancount, nscount, arcount; + u_int opcode, rcode, id; - if ((_res.options & RES_INIT) == 0 && res_init() == -1) + if (ns_initparse(msg, len, &handle) < 0) { + fprintf(file, ";; ns_initparse: %s\n", strerror(errno)); return; - -#define TruncTest(x) if (x > endMark) goto trunc -#define ErrorTest(x) if (x == NULL) goto error + } + opcode = ns_msg_getflag(handle, ns_f_opcode); + rcode = ns_msg_getflag(handle, ns_f_rcode); + id = ns_msg_id(handle); + qdcount = ns_msg_count(handle, ns_s_qd); + ancount = ns_msg_count(handle, ns_s_an); + nscount = ns_msg_count(handle, ns_s_ns); + arcount = ns_msg_count(handle, ns_s_ar); /* * Print header fields. */ - hp = (HEADER *)msg; - cp = msg + HFIXEDSZ; - endMark = msg + len; - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { - fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d", - _res_opcodes[hp->opcode], - _res_resultcodes[hp->rcode], - ntohs(hp->id)); - putc('\n', file); - } - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX)) + if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX) || rcode) + fprintf(file, + ";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n", + _res_opcodes[opcode], p_rcode(rcode), id); + if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEADX)) putc(';', file); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { + if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD2)) { fprintf(file, "; flags:"); - if (hp->qr) + if (ns_msg_getflag(handle, ns_f_qr)) fprintf(file, " qr"); - if (hp->aa) + if (ns_msg_getflag(handle, ns_f_aa)) fprintf(file, " aa"); - if (hp->tc) + if (ns_msg_getflag(handle, ns_f_tc)) fprintf(file, " tc"); - if (hp->rd) + if (ns_msg_getflag(handle, ns_f_rd)) fprintf(file, " rd"); - if (hp->ra) + if (ns_msg_getflag(handle, ns_f_ra)) fprintf(file, " ra"); - if (hp->unused) - fprintf(file, " UNUSED-BIT-ON"); - if (hp->ad) + if (ns_msg_getflag(handle, ns_f_z)) + fprintf(file, " ??"); + if (ns_msg_getflag(handle, ns_f_ad)) fprintf(file, " ad"); - if (hp->cd) + if (ns_msg_getflag(handle, ns_f_cd)) fprintf(file, " cd"); } - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { - fprintf(file, "; Ques: %d", ntohs(hp->qdcount)); - fprintf(file, ", Ans: %d", ntohs(hp->ancount)); - fprintf(file, ", Auth: %d", ntohs(hp->nscount)); - fprintf(file, ", Addit: %d", ntohs(hp->arcount)); + if ((!statp->pfcode) || (statp->pfcode & RES_PRF_HEAD1)) { + fprintf(file, "; %s: %d", + p_section(ns_s_qd, opcode), qdcount); + fprintf(file, ", %s: %d", + p_section(ns_s_an, opcode), ancount); + fprintf(file, ", %s: %d", + p_section(ns_s_ns, opcode), nscount); + fprintf(file, ", %s: %d", + p_section(ns_s_ar, opcode), arcount); } - if ((!_res.pfcode) || (_res.pfcode & + if ((!statp->pfcode) || (statp->pfcode & (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { putc('\n',file); } /* - * Print question records. + * Print the various sections. */ - if ((n = ntohs(hp->qdcount))) { - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - fprintf(file, ";; QUESTIONS:\n"); - while (--n >= 0) { - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - fprintf(file, ";;\t"); - TruncTest(cp); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - cp = p_cdnname(cp, msg, len, file); - else { - int n; - char name[MAXDNAME]; - - if ((n = dn_expand(msg, msg+len, cp, name, - sizeof name)) < 0) - cp = NULL; - else - cp += n; - } - ErrorTest(cp); - TruncTest(cp); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - fprintf(file, ", type = %s", - __p_type(_getshort((u_char*)cp))); - cp += INT16SZ; - TruncTest(cp); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - fprintf(file, ", class = %s\n", - __p_class(_getshort((u_char*)cp))); - cp += INT16SZ; - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) - putc('\n', file); - } - } - /* - * Print authoritative answer records - */ - TruncTest(cp); - cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file, - ";; ANSWERS:\n"); - ErrorTest(cp); - - /* - * print name server records - */ - TruncTest(cp); - cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file, - ";; AUTHORITY RECORDS:\n"); - ErrorTest(cp); - - TruncTest(cp); - /* - * print additional records - */ - cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file, - ";; ADDITIONAL RECORDS:\n"); - ErrorTest(cp); - return; - trunc: - fprintf(file, "\n;; ...truncated\n"); - return; - error: - fprintf(file, "\n;; ...malformed\n"); -} - -void -__fp_query(msg, file) - const u_char *msg; - FILE *file; -{ - fp_nquery(msg, PACKETSZ, file); + do_section(statp, &handle, ns_s_qd, RES_PRF_QUES, file); + do_section(statp, &handle, ns_s_an, RES_PRF_ANS, file); + do_section(statp, &handle, ns_s_ns, RES_PRF_AUTH, file); + do_section(statp, &handle, ns_s_ar, RES_PRF_ADD, file); + if (qdcount == 0 && ancount == 0 && + nscount == 0 && arcount == 0) + putc('\n', file); } const u_char * -__p_cdnname(cp, msg, len, file) - const u_char *cp, *msg; - int len; - FILE *file; -{ +p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) { char name[MAXDNAME]; int n; @@ -425,19 +278,15 @@ __p_cdnname(cp, msg, len, file) } const u_char * -__p_cdname(cp, msg, file) - const u_char *cp, *msg; - FILE *file; -{ +p_cdname(const u_char *cp, const u_char *msg, FILE *file) { return (p_cdnname(cp, msg, PACKETSZ, file)); } - /* Return a fully-qualified domain name from a compressed name (with length supplied). */ const u_char * -__p_fqnname(cp, msg, msglen, name, namelen) +p_fqnname(cp, msg, msglen, name, namelen) const u_char *cp, *msg; int msglen; char *name; @@ -447,9 +296,9 @@ __p_fqnname(cp, msg, msglen, name, namelen) if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0) return (NULL); - newlen = strlen (name); + newlen = strlen(name); if (newlen == 0 || name[newlen - 1] != '.') { - if (newlen+1 >= namelen) /* Lack space for final dot */ + if (newlen + 1 >= namelen) /* Lack space for final dot */ return (NULL); else strcpy(name + newlen, "."); @@ -457,18 +306,14 @@ __p_fqnname(cp, msg, msglen, name, namelen) return (cp + n); } -/* XXX: the rest of these functions need to become length-limited, too. (vix) - */ +/* XXX: the rest of these functions need to become length-limited, too. */ const u_char * -__p_fqname(cp, msg, file) - const u_char *cp, *msg; - FILE *file; -{ +p_fqname(const u_char *cp, const u_char *msg, FILE *file) { char name[MAXDNAME]; const u_char *n; - n = __p_fqnname(cp, msg, MAXCDNAME, name, sizeof name); + n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name); if (n == NULL) return (NULL); fputs(name, file); @@ -476,398 +321,6 @@ __p_fqname(cp, msg, file) } /* - * Print resource record fields in human readable form. - */ -const u_char * -__p_rr(cp, msg, file) - const u_char *cp, *msg; - FILE *file; -{ - int type, class, dlen, n, c; - struct in_addr inaddr; - const u_char *cp1, *cp2; - u_int32_t tmpttl, t; - int lcnt; - u_int16_t keyflags; - char rrname[MAXDNAME]; /* The fqdn of this RR */ - char base64_key[MAX_KEY_BASE64]; - - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - __set_h_errno (NETDB_INTERNAL); - return (NULL); - } - cp = __p_fqnname(cp, msg, MAXCDNAME, rrname, sizeof rrname); - if (!cp) - return (NULL); /* compression error */ - fputs(rrname, file); - - type = _getshort((u_char*)cp); - cp += INT16SZ; - class = _getshort((u_char*)cp); - cp += INT16SZ; - tmpttl = _getlong((u_char*)cp); - cp += INT32SZ; - dlen = _getshort((u_char*)cp); - cp += INT16SZ; - cp1 = cp; - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) - fprintf(file, "\t%lu", (u_long)tmpttl); - if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) - fprintf(file, "\t%s", __p_class(class)); - fprintf(file, "\t%s", __p_type(type)); - /* - * Print type specific data, if appropriate - */ - switch (type) { - case T_A: - switch (class) { - case C_IN: - case C_HS: - bcopy(cp, (char *)&inaddr, INADDRSZ); - if (dlen == 4) { - fprintf(file, "\t%s", inet_ntoa(inaddr)); - cp += dlen; - } else if (dlen == 7) { - char *address; - u_char protocol; - u_short port; - - address = inet_ntoa(inaddr); - cp += INADDRSZ; - protocol = *(u_char*)cp; - cp += sizeof (u_char); - port = _getshort((u_char*)cp); - cp += INT16SZ; - fprintf(file, "\t%s\t; proto %d, port %d", - address, protocol, port); - } - break; - default: - cp += dlen; - } - break; - case T_CNAME: - case T_MB: - case T_MG: - case T_MR: - case T_NS: - case T_PTR: - putc('\t', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - - case T_HINFO: - case T_ISDN: - cp2 = cp + dlen; - (void) fputs("\t\"", file); - if ((n = (unsigned char) *cp++) != 0) { - for (c = n; c > 0 && cp < cp2; c--) { - if (strchr("\n\"\\", *cp)) - (void) putc('\\', file); - (void) putc(*cp++, file); - } - } - putc('"', file); - if (cp < cp2 && (n = (unsigned char) *cp++) != 0) { - (void) fputs ("\t\"", file); - for (c = n; c > 0 && cp < cp2; c--) { - if (strchr("\n\"\\", *cp)) - (void) putc('\\', file); - (void) putc(*cp++, file); - } - putc('"', file); - } else if (type == T_HINFO) { - (void) fputs("\"?\"", file); - fprintf(file, "\n;; *** Warning *** OS-type missing"); - } - break; - - case T_SOA: - putc('\t', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - putc(' ', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - fputs(" (\n", file); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", - (u_long)t, __p_time(t)); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu\t; retry (%s)\n", - (u_long)t, __p_time(t)); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu\t; expire (%s)\n", - (u_long)t, __p_time(t)); - t = _getlong((u_char*)cp); cp += INT32SZ; - fprintf(file, "\t\t\t%lu )\t; minimum (%s)", - (u_long)t, __p_time(t)); - break; - - case T_MX: - case T_AFSDB: - case T_RT: - fprintf(file, "\t%d ", _getshort((u_char*)cp)); - cp += INT16SZ; - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - - case T_PX: - fprintf(file, "\t%d ", _getshort((u_char*)cp)); - cp += INT16SZ; - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - putc(' ', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - - case T_X25: - cp2 = cp + dlen; - (void) fputs("\t\"", file); - if ((n = (unsigned char) *cp++) != 0) { - for (c = n; c > 0 && cp < cp2; c--) { - if (strchr("\n\"\\", *cp)) - (void) putc('\\', file); - (void) putc(*cp++, file); - } - } - putc('"', file); - break; - - case T_TXT: - (void) putc('\t', file); - cp2 = cp1 + dlen; - while (cp < cp2) { - putc('"', file); - if ((n = (unsigned char) *cp++)) { - for (c = n; c > 0 && cp < cp2; c--) { - if (strchr("\n\"\\", *cp)) - (void) putc('\\', file); - (void) putc(*cp++, file); - } - } - putc('"', file); - if (cp < cp2) - putc(' ', file); - } - break; - - case T_NSAP: - (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL)); - cp += dlen; - break; - - case T_AAAA: { - char t[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - - fprintf(file, "\t%s", inet_ntop(AF_INET6, cp, t, sizeof t)); - cp += dlen; - break; - } - - case T_LOC: { - char t[255]; - - (void) fprintf(file, "\t%s", loc_ntoa(cp, t)); - cp += dlen; - break; - } - - case T_NAPTR: { - u_int order, preference; - - order = _getshort(cp); cp += INT16SZ; - preference = _getshort(cp); cp += INT16SZ; - fprintf(file, "\t%u %u ",order, preference); - /* Flags */ - n = *cp++; - fprintf(file,"\"%.*s\" ", (int)n, cp); - cp += n; - /* Service */ - n = *cp++; - fprintf(file,"\"%.*s\" ", (int)n, cp); - cp += n; - /* Regexp */ - n = *cp++; - fprintf(file,"\"%.*s\" ", (int)n, cp); - cp += n; - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - } - - case T_SRV: { - u_int priority, weight, port; - - priority = _getshort(cp); cp += INT16SZ; - weight = _getshort(cp); cp += INT16SZ; - port = _getshort(cp); cp += INT16SZ; - fprintf(file, "\t%u %u %u ", priority, weight, port); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - } - - case T_MINFO: - case T_RP: - putc('\t', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - putc(' ', file); - if ((cp = p_fqname(cp, msg, file)) == NULL) - return (NULL); - break; - - case T_UINFO: - putc('\t', file); - fputs((char *)cp, file); - cp += dlen; - break; - - case T_UID: - case T_GID: - if (dlen == 4) { - fprintf(file, "\t%u", _getlong((u_char*)cp)); - cp += INT32SZ; - } - break; - - case T_WKS: - if (dlen < INT32SZ + 1) - break; - bcopy(cp, (char *)&inaddr, INADDRSZ); - cp += INT32SZ; - fprintf(file, "\t%s %s ( ", - inet_ntoa(inaddr), - deproto((int) *cp)); - cp += sizeof (u_char); - n = 0; - lcnt = 0; - while (cp < cp1 + dlen) { - c = *cp++; - do { - if (c & 0200) { - if (lcnt == 0) { - fputs("\n\t\t\t", file); - lcnt = 5; - } - fputs(dewks(n), file); - putc(' ', file); - lcnt--; - } - c <<= 1; - } while (++n & 07); - } - putc(')', file); - break; - - case T_KEY: - putc('\t', file); - keyflags = _getshort(cp); - cp += 2; - fprintf(file,"0x%04x", keyflags ); /* flags */ - fprintf(file," %u", *cp++); /* protocol */ - fprintf(file," %u (", *cp++); /* algorithm */ - - n = b64_ntop(cp, (cp1 + dlen) - cp, - base64_key, sizeof base64_key); - for (c = 0; c < n; ++c) { - if (0 == (c & 0x3F)) - fprintf(file, "\n\t"); - putc(base64_key[c], file); /* public key data */ - } - - fprintf(file, " )"); - if (n < 0) - fprintf(file, "\t; BAD BASE64"); - fflush(file); - cp = cp1 + dlen; - break; - - case T_SIG: - type = _getshort((u_char*)cp); - cp += INT16SZ; - fprintf(file, " %s", p_type(type)); - fprintf(file, "\t%d", *cp++); /* algorithm */ - /* Check label value and print error if wrong. */ - n = *cp++; - c = dn_count_labels (rrname); - if (n != c) - fprintf(file, "\t; LABELS WRONG (%d should be %d)\n\t", - n, c); - /* orig ttl */ - n = _getlong((u_char*)cp); - if ((u_int32_t) n != tmpttl) - fprintf(file, " %u", n); - cp += INT32SZ; - /* sig expire */ - fprintf(file, " (\n\t%s", - __p_secstodate(_getlong((u_char*)cp))); - cp += INT32SZ; - /* time signed */ - fprintf(file, " %s", __p_secstodate(_getlong((u_char*)cp))); - cp += INT32SZ; - /* sig footprint */ - fprintf(file," %u ", _getshort((u_char*)cp)); - cp += INT16SZ; - /* signer's name */ - cp = p_fqname(cp, msg, file); - n = b64_ntop(cp, (cp1 + dlen) - cp, - base64_key, sizeof base64_key); - for (c = 0; c < n; c++) { - if (0 == (c & 0x3F)) - fprintf (file, "\n\t"); - putc(base64_key[c], file); /* signature */ - } - /* Clean up... */ - fprintf(file, " )"); - if (n < 0) - fprintf(file, "\t; BAD BASE64"); - fflush(file); - cp = cp1+dlen; - break; - -#ifdef ALLOW_T_UNSPEC - case T_UNSPEC: - { - int NumBytes = 8; - u_char *DataPtr; - int i; - - if (dlen < NumBytes) NumBytes = dlen; - fprintf(file, "\tFirst %d bytes of hex data:", - NumBytes); - for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) - fprintf(file, " %x", *DataPtr); - cp += dlen; - } - break; -#endif /* ALLOW_T_UNSPEC */ - - default: - fprintf(file, "\t?%d?", type); - cp += dlen; - } -#if 0 - fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl)); -#else - putc('\n', file); -#endif - if (cp - cp1 != dlen) { - fprintf(file, - ";; packet size error (found %lu, dlen was %d)\n", - (unsigned long) (cp - cp1), dlen); - cp = NULL; - } - return (cp); -} - -/* * Names of RR classes and qclasses. Classes and qclasses are the same, except * that C_ANY is a qclass but not a class. (You can ask for records of class * C_ANY, but you can't have any records of that class in the database.) @@ -878,7 +331,45 @@ const struct res_sym __p_class_syms[] = { {C_HS, "HS"}, {C_HS, "HESIOD"}, {C_ANY, "ANY"}, - {C_IN, (char *)0} + {C_NONE, "NONE"}, + {C_IN, (char *)0} +}; + +/* + * Names of message sections. + */ +const struct res_sym __p_default_section_syms[] = { + {ns_s_qd, "QUERY"}, + {ns_s_an, "ANSWER"}, + {ns_s_ns, "AUTHORITY"}, + {ns_s_ar, "ADDITIONAL"}, + {0, (char *)0} +}; + +const struct res_sym __p_update_section_syms[] = { + {S_ZONE, "ZONE"}, + {S_PREREQ, "PREREQUISITE"}, + {S_UPDATE, "UPDATE"}, + {S_ADDT, "ADDITIONAL"}, + {0, (char *)0} +}; + +const struct res_sym __p_key_syms[] = { + {NS_ALG_MD5RSA, "RSA", "RSA KEY with MD5 hash"}, + {NS_ALG_DH, "DH", "Diffie Hellman"}, + {NS_ALG_DSA, "DSA", "Digital Signature Algorithm"}, + {NS_ALG_EXPIRE_ONLY, "EXPIREONLY", "No algorithm"}, + {NS_ALG_PRIVATE_OID, "PRIVATE", "Algorithm obtained from OID"}, + {0, NULL, NULL} +}; + +const struct res_sym __p_cert_syms[] = { + {cert_t_pkix, "PKIX", "PKIX (X.509v3) Certificate"}, + {cert_t_spki, "SPKI", "SPKI certificate"}, + {cert_t_pgp, "PGP", "PGP certificate"}, + {cert_t_url, "URL", "URL Private"}, + {cert_t_oid, "OID", "OID Private"}, + {0, NULL, NULL} }; /* @@ -887,67 +378,78 @@ const struct res_sym __p_class_syms[] = { * T_ANY, but you can't have any records of that type in the database.) */ const struct res_sym __p_type_syms[] = { - {T_A, "A", "address"}, - {T_NS, "NS", "name server"}, - {T_MD, "MD", "mail destination (deprecated)"}, - {T_MF, "MF", "mail forwarder (deprecated)"}, - {T_CNAME, "CNAME", "canonical name"}, - {T_SOA, "SOA", "start of authority"}, - {T_MB, "MB", "mailbox"}, - {T_MG, "MG", "mail group member"}, - {T_MR, "MR", "mail rename"}, - {T_NULL, "NULL", "null"}, - {T_WKS, "WKS", "well-known service (deprecated)"}, - {T_PTR, "PTR", "domain name pointer"}, - {T_HINFO, "HINFO", "host information"}, - {T_MINFO, "MINFO", "mailbox information"}, - {T_MX, "MX", "mail exchanger"}, - {T_TXT, "TXT", "text"}, - {T_RP, "RP", "responsible person"}, - {T_AFSDB, "AFSDB", "DCE or AFS server"}, - {T_X25, "X25", "X25 address"}, - {T_ISDN, "ISDN", "ISDN address"}, - {T_RT, "RT", "router"}, - {T_NSAP, "NSAP", "nsap address"}, - {T_NSAP_PTR, "NSAP_PTR", "domain name pointer"}, - {T_SIG, "SIG", "signature"}, - {T_KEY, "KEY", "key"}, - {T_PX, "PX", "mapping information"}, - {T_GPOS, "GPOS", "geographical position (withdrawn)"}, - {T_AAAA, "AAAA", "IPv6 address"}, - {T_LOC, "LOC", "location"}, - {T_NXT, "NXT", "next valid name (unimplemented)"}, - {T_EID, "EID", "endpoint identifier (unimplemented)"}, - {T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"}, - {T_SRV, "SRV", "server selection"}, - {T_ATMA, "ATMA", "ATM address (unimplemented)"}, - {T_IXFR, "IXFR", "incremental zone transfer"}, - {T_AXFR, "AXFR", "zone transfer"}, - {T_MAILB, "MAILB", "mailbox-related data (deprecated)"}, - {T_MAILA, "MAILA", "mail agent (deprecated)"}, - {T_UINFO, "UINFO", "user information (nonstandard)"}, - {T_UID, "UID", "user ID (nonstandard)"}, - {T_GID, "GID", "group ID (nonstandard)"}, - {T_NAPTR, "NAPTR", "URN Naming Authority"}, -#ifdef ALLOW_T_UNSPEC - {T_UNSPEC, "UNSPEC", "unspecified data (nonstandard)"}, -#endif /* ALLOW_T_UNSPEC */ - {T_ANY, "ANY", "\"any\""}, - {0, NULL, NULL} + {ns_t_a, "A", "address"}, + {ns_t_ns, "NS", "name server"}, + {ns_t_md, "MD", "mail destination (deprecated)"}, + {ns_t_mf, "MF", "mail forwarder (deprecated)"}, + {ns_t_cname, "CNAME", "canonical name"}, + {ns_t_soa, "SOA", "start of authority"}, + {ns_t_mb, "MB", "mailbox"}, + {ns_t_mg, "MG", "mail group member"}, + {ns_t_mr, "MR", "mail rename"}, + {ns_t_null, "NULL", "null"}, + {ns_t_wks, "WKS", "well-known service (deprecated)"}, + {ns_t_ptr, "PTR", "domain name pointer"}, + {ns_t_hinfo, "HINFO", "host information"}, + {ns_t_minfo, "MINFO", "mailbox information"}, + {ns_t_mx, "MX", "mail exchanger"}, + {ns_t_txt, "TXT", "text"}, + {ns_t_rp, "RP", "responsible person"}, + {ns_t_afsdb, "AFSDB", "DCE or AFS server"}, + {ns_t_x25, "X25", "X25 address"}, + {ns_t_isdn, "ISDN", "ISDN address"}, + {ns_t_rt, "RT", "router"}, + {ns_t_nsap, "NSAP", "nsap address"}, + {ns_t_nsap_ptr, "NSAP_PTR", "domain name pointer"}, + {ns_t_sig, "SIG", "signature"}, + {ns_t_key, "KEY", "key"}, + {ns_t_px, "PX", "mapping information"}, + {ns_t_gpos, "GPOS", "geographical position (withdrawn)"}, + {ns_t_aaaa, "AAAA", "IPv6 address"}, + {ns_t_loc, "LOC", "location"}, + {ns_t_nxt, "NXT", "next valid name (unimplemented)"}, + {ns_t_eid, "EID", "endpoint identifier (unimplemented)"}, + {ns_t_nimloc, "NIMLOC", "NIMROD locator (unimplemented)"}, + {ns_t_srv, "SRV", "server selection"}, + {ns_t_atma, "ATMA", "ATM address (unimplemented)"}, + {ns_t_tsig, "TSIG", "transaction signature"}, + {ns_t_ixfr, "IXFR", "incremental zone transfer"}, + {ns_t_axfr, "AXFR", "zone transfer"}, + {ns_t_zxfr, "ZXFR", "compressed zone transfer"}, + {ns_t_mailb, "MAILB", "mailbox-related data (deprecated)"}, + {ns_t_maila, "MAILA", "mail agent (deprecated)"}, + {ns_t_naptr, "NAPTR", "URN Naming Authority"}, + {ns_t_kx, "KX", "Key Exchange"}, + {ns_t_cert, "CERT", "Certificate"}, + {ns_t_any, "ANY", "\"any\""}, + {0, NULL, NULL} +}; + +/* + * Names of DNS rcodes. + */ +const struct res_sym __p_rcode_syms[] = { + {ns_r_noerror, "NOERROR", "no error"}, + {ns_r_formerr, "FORMERR", "format error"}, + {ns_r_servfail, "SERVFAIL", "server failed"}, + {ns_r_nxdomain, "NXDOMAIN", "no such domain name"}, + {ns_r_notimpl, "NOTIMP", "not implemented"}, + {ns_r_refused, "REFUSED", "refused"}, + {ns_r_yxdomain, "YXDOMAIN", "domain name exists"}, + {ns_r_yxrrset, "YXRRSET", "rrset exists"}, + {ns_r_nxrrset, "NXRRSET", "rrset doesn't exist"}, + {ns_r_notauth, "NOTAUTH", "not authoritative"}, + {ns_r_notzone, "NOTZONE", "Not in zone"}, + {ns_r_max, "", ""}, + {ns_r_badsig, "BADSIG", "bad signature"}, + {ns_r_badkey, "BADKEY", "bad key"}, + {ns_r_badtime, "BADTIME", "bad time"}, + {0, NULL, NULL} }; int -__sym_ston(syms, name, success) - const struct res_sym *syms; - char *name; - int *success; -{ -#ifdef _LIBC - /* Changed to prevent warning. --drepper@gnu */ - for (; syms->name != 0; syms++) { -#else - for (NULL; syms->name != 0; syms++) { -#endif +sym_ston(const struct res_sym *syms, const char *name, int *success) { + for ((void)NULL; syms->name != 0; syms++) { if (strcasecmp (name, syms->name) == 0) { if (success) *success = 1; @@ -956,50 +458,41 @@ __sym_ston(syms, name, success) } if (success) *success = 0; - return (syms->number); /* The default value. */ + return (syms->number); /* The default value. */ } const char * -__sym_ntos(syms, number, success) - const struct res_sym *syms; - int number; - int *success; -{ +sym_ntos(const struct res_sym *syms, int number, int *success) { static char unname[20]; #ifdef _LIBC /* Changed to prevent warning. --drepper@gnu */ for (; syms->name != 0; syms++) { #else - for (NULL; syms->name != 0; syms++) { + for ((void)NULL; syms->name != 0; syms++) { #endif - if (number == syms->number) { + if (number == syms->number) { if (success) *success = 1; return (syms->name); } } - sprintf (unname, "%d", number); + sprintf(unname, "%d", number); /* XXX nonreentrant */ if (success) *success = 0; return (unname); } - const char * -__sym_ntop(syms, number, success) - const struct res_sym *syms; - int number; - int *success; -{ +sym_ntop(const struct res_sym *syms, int number, int *success) { static char unname[20]; #ifdef _LIBC /* Changed to prevent warning. --drepper@gnu */ for (; syms->name != 0; syms++) { #else - for (NULL; syms->name != 0; syms++) { + for ((void)NULL; syms->name != 0; syms++) { #endif if (number == syms->number) { if (success) @@ -1007,39 +500,51 @@ __sym_ntop(syms, number, success) return (syms->humanname); } } - sprintf(unname, "%d", number); + sprintf(unname, "%d", number); /* XXX nonreentrant */ if (success) *success = 0; return (unname); } /* - * Return a string for the type + * Return a string for the type. */ const char * -__p_type(type) - int type; -{ - return (__sym_ntos (__p_type_syms, type, (int *)0)); +p_type(int type) { + return (sym_ntos(__p_type_syms, type, (int *)0)); } /* - * Return a mnemonic for class + * Return a string for the type. */ const char * -__p_class(class) - int class; -{ - return (__sym_ntos (__p_class_syms, class, (int *)0)); +p_section(int section, int opcode) { + const struct res_sym *symbols; + + switch (opcode) { + case ns_o_update: + symbols = __p_update_section_syms; + break; + default: + symbols = __p_default_section_syms; + break; + } + return (sym_ntos(symbols, section, (int *)0)); +} + +/* + * Return a mnemonic for class. + */ +const char * +p_class(int class) { + return (sym_ntos(__p_class_syms, class, (int *)0)); } /* * Return a mnemonic for an option */ const char * -__p_option(option) - u_long option; -{ +p_option(u_long option) { static char nbuf[40]; switch (option) { @@ -1055,63 +560,33 @@ __p_option(option) case RES_DNSRCH: return "dnsrch"; case RES_INSECURE1: return "insecure1"; case RES_INSECURE2: return "insecure2"; + /* XXX nonreentrant */ default: sprintf(nbuf, "?0x%lx?", (u_long)option); return (nbuf); } } /* - * Return a mnemonic for a time to live + * Return a mnemonic for a time to live. */ const char * -p_time(value) - u_int32_t value; -{ - static char nbuf[60]; - int secs, mins, hours, days; - register char *p; +p_time(u_int32_t value) { + static char nbuf[40]; /* XXX nonreentrant */ - if (value == 0) { - strcpy(nbuf, "0 secs"); - return (nbuf); - } - - secs = value % 60; - value /= 60; - mins = value % 60; - value /= 60; - hours = value % 24; - value /= 24; - days = value; - value = 0; - -#define PLURALIZE(x) x, (x == 1) ? "" : "s" - p = nbuf; - if (days) { - (void)sprintf(p, "%d day%s", PLURALIZE(days)); - while (*++p); - } - if (hours) { - if (days) - *p++ = ' '; - (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); - while (*++p); - } - if (mins) { - if (days || hours) - *p++ = ' '; - (void)sprintf(p, "%d min%s", PLURALIZE(mins)); - while (*++p); - } - if (secs || ! (days || hours || mins)) { - if (days || hours || mins) - *p++ = ' '; - (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); - } + if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0) + sprintf(nbuf, "%u", value); return (nbuf); } /* + * Return a string for the rcode. + */ +const char * +p_rcode(int rcode) { + return (sym_ntos(__p_rcode_syms, rcode, (int *)0)); +} + +/* * routines to convert between on-the-wire RR format and zone file format. * Does not contain conversion to/from decimal degrees; divide or multiply * by 60*60*1000 for that. @@ -1125,7 +600,7 @@ static const char * precsize_ntoa(prec) u_int8_t prec; { - static char retbuf[sizeof "90000000.00"]; + static char retbuf[sizeof "90000000.00"]; /* XXX nonreentrant */ unsigned long val; int mantissa, exponent; @@ -1143,47 +618,40 @@ static u_int8_t precsize_aton(strptr) char **strptr; { + unsigned int mval = 0, cmval = 0; u_int8_t retval = 0; char *cp; - int exponent = 0; - int mantissa = 0; + int exponent; + int mantissa; cp = *strptr; - while (isdigit(*cp)) { - if (mantissa == 0) - mantissa = *cp - '0'; - else - exponent++; - cp++; - } - if (*cp == '.') { + while (isdigit(*cp)) + mval = mval * 10 + (*cp++ - '0'); + + if (*cp == '.') { /* centimeters */ cp++; if (isdigit(*cp)) { - if (mantissa == 0) - mantissa = *cp - '0'; - else - exponent++; - cp++; - + cmval = (*cp++ - '0') * 10; if (isdigit(*cp)) { - if (mantissa == 0) - mantissa = *cp - '0'; - else - exponent++; - cp++; + cmval += (*cp++ - '0'); } - else - exponent++; } } - else - exponent += 2; + cmval = (mval * 100) + cmval; + + for (exponent = 0; exponent < 9; exponent++) + if (cmval < poweroften[exponent+1]) + break; + + mantissa = cmval / poweroften[exponent]; + if (mantissa > 9) + mantissa = 9; - if (mantissa == 0) - exponent = 0; retval = (mantissa << 4) | exponent; + *strptr = cp; + return (retval); } @@ -1193,7 +661,7 @@ latlon2ul(latlonstrptr,which) char **latlonstrptr; int *which; { - register char *cp; + char *cp; u_int32_t retval; int deg = 0, min = 0, secs = 0, secsfrac = 0; @@ -1331,7 +799,7 @@ loc_aton(ascii, binary) altsign = -1; cp++; } - + if (*cp == '+') cp++; @@ -1360,7 +828,7 @@ loc_aton(ascii, binary) goto defaults; siz = precsize_aton(&cp); - + while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */ cp++; @@ -1393,7 +861,7 @@ loc_aton(ascii, binary) PUTLONG(latit,bcp); PUTLONG(longit,bcp); PUTLONG(alt,bcp); - + return (16); /* size of RR in octets */ } @@ -1404,25 +872,30 @@ loc_ntoa(binary, ascii) char *ascii; { static char *error = "?"; - register const u_char *cp = binary; + static char tmpbuf[sizeof +"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"]; + const u_char *cp = binary; int latdeg, latmin, latsec, latsecfrac; int longdeg, longmin, longsec, longsecfrac; char northsouth, eastwest; int altmeters, altfrac, altsign; - const int referencealt = 100000 * 100; + const u_int32_t referencealt = 100000 * 100; int32_t latval, longval, altval; u_int32_t templ; u_int8_t sizeval, hpval, vpval, versionval; - + char *sizestr, *hpstr, *vpstr; versionval = *cp++; + if (ascii == NULL) + ascii = tmpbuf; + if (versionval) { - sprintf(ascii, "; error: unknown LOC RR version"); + (void) sprintf(ascii, "; error: unknown LOC RR version"); return (ascii); } @@ -1438,7 +911,7 @@ loc_ntoa(binary, ascii) longval = (templ - ((unsigned)1<<31)); GETLONG(templ, cp); - if (templ < (u_int32_t) referencealt) { /* below WGS 84 spheroid */ + if (templ < referencealt) { /* below WGS 84 spheroid */ altval = referencealt - templ; altsign = -1; } else { @@ -1503,14 +976,12 @@ loc_ntoa(binary, ascii) /* Return the number of DNS hierarchy levels in the name. */ int -__dn_count_labels(name) - char *name; -{ +dn_count_labels(const char *name) { int i, len, count; len = strlen(name); - - for(i = 0, count = 0; i < len; i++) { + for (i = 0, count = 0; i < len; i++) { + /* XXX need to check for \. or use named's nlabels(). */ if (name[i] == '.') count++; } @@ -1529,23 +1000,28 @@ __dn_count_labels(name) } -/* - * Make dates expressed in seconds-since-Jan-1-1970 easy to read. +/* + * Make dates expressed in seconds-since-Jan-1-1970 easy to read. * SIG records are required to be printed like this, by the Secure DNS RFC. */ char * -__p_secstodate (secs) - unsigned long secs; -{ - static char output[15]; /* YYYYMMDDHHMMSS and null */ +p_secstodate (u_long secs) { + /* XXX nonreentrant */ + static char output[15]; /* YYYYMMDDHHMMSS and null */ time_t clock = secs; - struct tm time; - - __gmtime_r(&clock, &time); - time.tm_year += 1900; - time.tm_mon += 1; + struct tm *time; + +#ifdef HAVE_TIME_R + struct time timebuf; + + time = gmtime_r(&clock, &timebuf); +#else + time = gmtime(&clock); +#endif + time->tm_year += 1900; + time->tm_mon += 1; sprintf(output, "%04d%02d%02d%02d%02d%02d", - time.tm_year, time.tm_mon, time.tm_mday, - time.tm_hour, time.tm_min, time.tm_sec); + time->tm_year, time->tm_mon, time->tm_mday, + time->tm_hour, time->tm_min, time->tm_sec); return (output); } |