malloc(0)->0 fixes.
[adns] / src / general.c
1 /*
2 * general.c
3 * - diagnostic functions
4 * - vbuf handling
5 */
6 /*
7 * This file is part of adns, which is Copyright (C) 1997, 1998 Ian Jackson
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24 #include <stdlib.h>
25
26 #include <arpa/inet.h>
27
28 #include "internal.h"
29
30 /* Core diagnostic functions */
31
32 void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent,
33 int serv, adns_query qu, const char *fmt, va_list al) {
34 const char *bef, *aft;
35 vbuf vb;
36 if (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent))) return;
37
38 fprintf(stderr,"adns%s: ",pfx);
39
40 vfprintf(stderr,fmt,al);
41
42 bef= " (";
43 aft= "\n";
44
45 if (qu && qu->query_dgram) {
46 adns__vbuf_init(&vb);
47 fprintf(stderr,"%sQNAME=%s, QTYPE=%s",
48 bef,
49 adns__diag_domain(qu->ads,-1,0, &vb,qu->flags,
50 qu->query_dgram,qu->query_dglen,DNS_HDRSIZE),
51 qu->typei ? qu->typei->name : "<unknown>");
52 bef=", "; aft=")\n";
53 }
54
55 if (serv>=0) {
56 fprintf(stderr,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr));
57 bef=", "; aft=")\n";
58 }
59
60 fputs(aft,stderr);
61 }
62
63 void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
64 va_list al;
65
66 va_start(al,fmt);
67 adns__vdiag(ads," debug",0,serv,qu,fmt,al);
68 va_end(al);
69 }
70
71 void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
72 va_list al;
73
74 va_start(al,fmt);
75 adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al);
76 va_end(al);
77 }
78
79 void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) {
80 va_list al;
81
82 va_start(al,fmt);
83 adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al);
84 va_end(al);
85 }
86
87 /* vbuf functions */
88
89 void adns__vbuf_init(vbuf *vb) {
90 vb->used= vb->avail= 0; vb->buf= 0;
91 }
92
93 int adns__vbuf_ensure(vbuf *vb, int want) {
94 void *nb;
95
96 if (vb->avail >= want) return 1;
97 nb= realloc(vb->buf,want); if (!nb) return 0;
98 vb->buf= nb;
99 vb->avail= want;
100 return 1;
101 }
102
103 void adns__vbuf_appendq(vbuf *vb, const byte *data, int len) {
104 memcpy(vb->buf+vb->used,data,len);
105 vb->used+= len;
106 }
107
108 int adns__vbuf_append(vbuf *vb, const byte *data, int len) {
109 int newlen;
110 void *nb;
111
112 newlen= vb->used+len;
113 if (vb->avail < newlen) {
114 if (newlen<20) newlen= 20;
115 newlen <<= 1;
116 nb= realloc(vb->buf,newlen);
117 if (!nb) { newlen= vb->used+len; nb= realloc(vb->buf,newlen); }
118 if (!nb) return 0;
119 vb->buf= nb;
120 vb->avail= newlen;
121 }
122 adns__vbuf_appendq(vb,data,len);
123 return 1;
124 }
125
126 void adns__vbuf_free(vbuf *vb) {
127 free(vb->buf);
128 adns__vbuf_init(vb);
129 }
130
131 /* Additional diagnostic functions */
132
133 const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb,
134 int flags, const byte *dgram, int dglen, int cbyte) {
135 adns_status st;
136
137 st= adns__parse_domain(ads,serv,qu,vb, flags,dgram,dglen,&cbyte,dglen);
138 if (st == adns_s_nolocalmem) {
139 return "<cannot report domain... out of memory>";
140 }
141 if (st) {
142 vb->used= 0;
143 if (!(adns__vbuf_appendstr(vb,"<bad format... ") &&
144 adns__vbuf_appendstr(vb,adns_strerror(st)) &&
145 adns__vbuf_appendstr(vb,">") &&
146 adns__vbuf_append(vb,"",1))) {
147 return "<cannot report bad format... out of memory>";
148 }
149 }
150 if (!vb->used) {
151 adns__vbuf_appendstr(vb,"<truncated ...>");
152 adns__vbuf_append(vb,"",1);
153 }
154 return vb->buf;
155 }
156
157 const char *adns_strerror(adns_status st) {
158 static char buf[100];
159 snprintf(buf,sizeof(buf),"code %d",st);
160 return buf;
161 }