e576be50 |
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 | |
3955725c |
24 | #include <stdlib.h> |
25 | |
26 | #include <arpa/inet.h> |
27 | |
e576be50 |
28 | #include "internal.h" |
29 | |
30 | /* Core diagnostic functions */ |
31 | |
32 | void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, |
3955725c |
33 | int serv, adns_query qu, const char *fmt, va_list al) { |
e576be50 |
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, |
3955725c |
49 | adns__diag_domain(qu->ads,-1,0, &vb,qu->flags, |
50 | qu->query_dgram,qu->query_dglen,DNS_HDRSIZE), |
e576be50 |
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) { |
a49a6d7b |
114 | if (newlen<20) newlen= 20; |
e576be50 |
115 | newlen <<= 1; |
116 | nb= realloc(vb->buf,newlen); |
a49a6d7b |
117 | if (!nb) { newlen= vb->used+len; nb= realloc(vb->buf,newlen); } |
e576be50 |
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 | |
f759e52e |
126 | int adns__vbuf_appendstr(vbuf *vb, const char *data) { |
127 | int l; |
9557e604 |
128 | l= strlen(data); |
f759e52e |
129 | return adns__vbuf_append(vb,data,l); |
130 | } |
131 | |
a49a6d7b |
132 | void adns__vbuf_free(vbuf *vb) { |
133 | free(vb->buf); |
134 | adns__vbuf_init(vb); |
135 | } |
136 | |
e576be50 |
137 | /* Additional diagnostic functions */ |
138 | |
139 | const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, |
140 | int flags, const byte *dgram, int dglen, int cbyte) { |
141 | adns_status st; |
142 | |
3955725c |
143 | st= adns__parse_domain(ads,serv,qu,vb, flags,dgram,dglen,&cbyte,dglen); |
144 | if (st == adns_s_nolocalmem) { |
e576be50 |
145 | return "<cannot report domain... out of memory>"; |
146 | } |
147 | if (st) { |
148 | vb->used= 0; |
149 | if (!(adns__vbuf_appendstr(vb,"<bad format... ") && |
150 | adns__vbuf_appendstr(vb,adns_strerror(st)) && |
151 | adns__vbuf_appendstr(vb,">") && |
152 | adns__vbuf_append(vb,"",1))) { |
153 | return "<cannot report bad format... out of memory>"; |
154 | } |
155 | } |
3955725c |
156 | if (!vb->used) { |
e576be50 |
157 | adns__vbuf_appendstr(vb,"<truncated ...>"); |
158 | adns__vbuf_append(vb,"",1); |
159 | } |
160 | return vb->buf; |
161 | } |
162 | |
163 | const char *adns_strerror(adns_status st) { |
164 | static char buf[100]; |
165 | snprintf(buf,sizeof(buf),"code %d",st); |
166 | return buf; |
167 | } |