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 | |
24 | #include "internal.h" |
25 | |
26 | /* Core diagnostic functions */ |
27 | |
28 | void adns__vdiag(adns_state ads, const char *pfx, adns_initflags prevent, |
29 | int serv, const char *fmt, adns_query qu, va_list al) { |
30 | const char *bef, *aft; |
31 | vbuf vb; |
32 | if (!(ads->iflags & adns_if_debug) && (!prevent || (ads->iflags & prevent))) return; |
33 | |
34 | fprintf(stderr,"adns%s: ",pfx); |
35 | |
36 | vfprintf(stderr,fmt,al); |
37 | |
38 | bef= " ("; |
39 | aft= "\n"; |
40 | |
41 | if (qu && qu->query_dgram) { |
42 | adns__vbuf_init(&vb); |
43 | fprintf(stderr,"%sQNAME=%s, QTYPE=%s", |
44 | bef, |
45 | adns__diag_domain(ads,-1,0,&vb,qu->query_dgram,qu->query_dglen,DNS_HDRSIZE), |
46 | qu->typei ? qu->typei->name : "<unknown>"); |
47 | bef=", "; aft=")\n"; |
48 | } |
49 | |
50 | if (serv>=0) { |
51 | fprintf(stderr,"%sNS=%s",bef,inet_ntoa(ads->servers[serv].addr)); |
52 | bef=", "; aft=")\n"; |
53 | } |
54 | |
55 | fputs(aft,stderr); |
56 | } |
57 | |
58 | void adns__debug(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { |
59 | va_list al; |
60 | |
61 | va_start(al,fmt); |
62 | adns__vdiag(ads," debug",0,serv,qu,fmt,al); |
63 | va_end(al); |
64 | } |
65 | |
66 | void adns__warn(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { |
67 | va_list al; |
68 | |
69 | va_start(al,fmt); |
70 | adns__vdiag(ads," warning",adns_if_noerrprint|adns_if_noserverwarn,serv,qu,fmt,al); |
71 | va_end(al); |
72 | } |
73 | |
74 | void adns__diag(adns_state ads, int serv, adns_query qu, const char *fmt, ...) { |
75 | va_list al; |
76 | |
77 | va_start(al,fmt); |
78 | adns__vdiag(ads,"",adns_if_noerrprint,serv,qu,fmt,al); |
79 | va_end(al); |
80 | } |
81 | |
82 | /* vbuf functions */ |
83 | |
84 | void adns__vbuf_init(vbuf *vb) { |
85 | vb->used= vb->avail= 0; vb->buf= 0; |
86 | } |
87 | |
88 | int adns__vbuf_ensure(vbuf *vb, int want) { |
89 | void *nb; |
90 | |
91 | if (vb->avail >= want) return 1; |
92 | nb= realloc(vb->buf,want); if (!nb) return 0; |
93 | vb->buf= nb; |
94 | vb->avail= want; |
95 | return 1; |
96 | } |
97 | |
98 | void adns__vbuf_appendq(vbuf *vb, const byte *data, int len) { |
99 | memcpy(vb->buf+vb->used,data,len); |
100 | vb->used+= len; |
101 | } |
102 | |
103 | int adns__vbuf_append(vbuf *vb, const byte *data, int len) { |
104 | int newlen; |
105 | void *nb; |
106 | |
107 | newlen= vb->used+len; |
108 | if (vb->avail < newlen) { |
109 | newlen <<= 1; |
110 | nb= realloc(vb->buf,newlen); |
111 | if (!nb) { newlen >>= 1; nb= realloc(vb->buf,newlen); } |
112 | if (!nb) return 0; |
113 | vb->buf= nb; |
114 | vb->avail= newlen; |
115 | } |
116 | adns__vbuf_appendq(vb,data,len); |
117 | return 1; |
118 | } |
119 | |
120 | /* Additional diagnostic functions */ |
121 | |
122 | const char *adns__diag_domain(adns_state ads, int serv, adns_query qu, vbuf *vb, |
123 | int flags, const byte *dgram, int dglen, int cbyte) { |
124 | adns_status st; |
125 | |
126 | st= adns__parse_domain(ads,serv,vb,qu->flags, dgram,dglen, &cbyte,dglen); |
127 | if (st == adns_s_nomemory) { |
128 | return "<cannot report domain... out of memory>"; |
129 | } |
130 | if (st) { |
131 | vb->used= 0; |
132 | if (!(adns__vbuf_appendstr(vb,"<bad format... ") && |
133 | adns__vbuf_appendstr(vb,adns_strerror(st)) && |
134 | adns__vbuf_appendstr(vb,">") && |
135 | adns__vbuf_append(vb,"",1))) { |
136 | return "<cannot report bad format... out of memory>"; |
137 | } |
138 | } |
139 | if (!vb.used) { |
140 | adns__vbuf_appendstr(vb,"<truncated ...>"); |
141 | adns__vbuf_append(vb,"",1); |
142 | } |
143 | return vb->buf; |
144 | } |
145 | |
146 | const char *adns_strerror(adns_status st) { |
147 | static char buf[100]; |
148 | snprintf(buf,sizeof(buf),"code %d",st); |
149 | return buf; |
150 | } |