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) { |
114 | newlen <<= 1; |
115 | nb= realloc(vb->buf,newlen); |
116 | if (!nb) { newlen >>= 1; nb= realloc(vb->buf,newlen); } |
117 | if (!nb) return 0; |
118 | vb->buf= nb; |
119 | vb->avail= newlen; |
120 | } |
121 | adns__vbuf_appendq(vb,data,len); |
122 | return 1; |
123 | } |
124 | |
125 | /* Additional diagnostic functions */ |
126 | |
127 | const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, |
128 | int flags, const byte *dgram, int dglen, int cbyte) { |
129 | adns_status st; |
130 | |
3955725c |
131 | st= adns__parse_domain(ads,serv,qu,vb, flags,dgram,dglen,&cbyte,dglen); |
132 | if (st == adns_s_nolocalmem) { |
e576be50 |
133 | return "<cannot report domain... out of memory>"; |
134 | } |
135 | if (st) { |
136 | vb->used= 0; |
137 | if (!(adns__vbuf_appendstr(vb,"<bad format... ") && |
138 | adns__vbuf_appendstr(vb,adns_strerror(st)) && |
139 | adns__vbuf_appendstr(vb,">") && |
140 | adns__vbuf_append(vb,"",1))) { |
141 | return "<cannot report bad format... out of memory>"; |
142 | } |
143 | } |
3955725c |
144 | if (!vb->used) { |
e576be50 |
145 | adns__vbuf_appendstr(vb,"<truncated ...>"); |
146 | adns__vbuf_append(vb,"",1); |
147 | } |
148 | return vb->buf; |
149 | } |
150 | |
151 | const char *adns_strerror(adns_status st) { |
152 | static char buf[100]; |
153 | snprintf(buf,sizeof(buf),"code %d",st); |
154 | return buf; |
155 | } |