5db99a2e |
1 | /**/ |
2 | |
3 | #include <arpa/nameser.h> |
4 | |
5 | #include "adns-internal.h" |
6 | |
7 | #define LIST_UNLINK(list,node) \ |
8 | do { \ |
9 | if ((node)->back) (node)->back->next= (node)->next; \ |
10 | else (list).head= (node)->next; \ |
11 | if ((node)->next) (node)->next->back= (node)->back; \ |
12 | else (list).tail= (node)->back; \ |
13 | } while(0) |
14 | |
15 | #define LIST_LINK_TAIL(list,node) \ |
16 | do { \ |
17 | (node)->back= 0; \ |
18 | (node)->next= (list).tail; \ |
19 | if (list).tail (list).tail->back= (node); else (list).head= (node); \ |
20 | (list).tail= (node); \ |
21 | } while(0) |
22 | |
23 | void addserver(adns_state ads, struct in_addr addr) { |
24 | if (ads->nservers>=MAXSERVERS) { |
25 | if (ads->flags & adns_if_debug) |
26 | fprintf(stderr,"adns: too many nameservers, ignoring %s", |
27 | inet_ntoa(addr)); |
28 | } else { |
29 | ads->servers[ads->nservers].addr= addr; |
30 | ads->servers[ads->nservers].tcpsocket= -1; |
31 | ads->nservers++; |
32 | } |
33 | } |
34 | |
35 | void readconfig(adns_state ads, const char *filename) { |
36 | } |
37 | |
38 | void readconfigenv(adns_state ads, const char *envvar) { |
39 | const char *filename; |
40 | |
41 | if (flags & adns_if_noenv) return; |
42 | filename= getenv(envvar); if (!filename) return; |
43 | readconfig(ads,filename); |
44 | } |
45 | |
46 | int adns_init(adns_state *ads_r, int flags) { |
47 | adns_state ads; |
48 | const char *cfile; |
49 | |
50 | ads= malloc(sizeof(*ads)); if (!ads) return errno; |
51 | ads->queue.head= ads->queue.tail= 0; |
52 | ads->timew.head= ads->timew.tail= 0; |
53 | ads->child.head= ads->child.tail= 0; |
54 | ads->ready.head= ads->ready.tail= 0; |
55 | ads->udpsocket= -1; |
56 | ads->qbufavail= 0; |
57 | ads->qbuf= 0; |
58 | ads->tcpbufavail= ads->tcpbufused= ads->tcpbufdone= 0; |
59 | ads->tcpbuf= 0; |
60 | ads->flags= flags; |
61 | ads->nservers= 0; |
62 | |
63 | readconfig(ads,"/etc/resolv.conf"); |
64 | readconfigenv(ads,"RES_CONF"); |
65 | readconfigenv(ads,"ADNS_RES_CONF"); |
66 | if (!ads->nservers) { |
67 | if (ads->flags & adns_if_debug) |
68 | fprintf(stderr,"adns: no nameservers, using localhost\n"); |
69 | addserver(ads,INADDR_LOOPBACK); |
70 | } |
71 | |
72 | *ads_r= ads; |
73 | return 0; |
74 | } |
75 | |
76 | void query_fail(adns_state ads, adns_query qu, ands_status stat) { |
77 | struct adns_answer ans; |
78 | |
79 | ans= qu->answer; |
80 | if (!ans) ans= malloc(sizeof(*qu->answer)); |
81 | if (ans) { |
82 | ans->status= stat; |
83 | ans->cname= 0; |
84 | ans->type= qu->type; |
85 | ans->nrrs= 0; |
86 | } |
87 | qu->answer= ans; |
88 | LIST_LINK_TAIL(ads.ready,qu); |
89 | } |
90 | |
91 | void adns_event(adns_state ads, |
92 | fd_set *readfds, fd_set *writefds, fd_set *exceptfds, |
93 | int *maxfd, struct timeval *tv) { |
94 | for ( |
95 | } |
96 | |
97 | int adns_submit(adns_state ads, |
98 | const char *owner, |
99 | adns_rrtype type, |
100 | int flags, |
101 | void *context, |
102 | adns_query *query_r) { |
103 | adns_query qu; |
104 | adns_status stat; |
105 | int ol, r; |
106 | |
107 | stat= 0; |
108 | ol= strlen(owner); |
109 | if (ol>MAXDNAME+1) { stat= ands_s_invaliddomain; ol= 0; } |
110 | if (ol>0 && owner[ol-1]=='.') { flags &= ~adns_f_search; ol--; } |
111 | qu= malloc(sizeof(*qu)+ol+1); if (!qu) return errno; |
112 | qu->next= qu->back= qu->parent= qu->child= 0; |
113 | qu->type= type; |
114 | qu->answer= 0; |
115 | qu->flags= flags; |
116 | qu->context= context; |
117 | qu->retries= 0; |
118 | qu->server= 0; |
119 | memcpy(qu->owner,owner,ol); qu->owner[ol]= 0; |
120 | if (stat) { |
121 | query_fail(ads,qu,stat); |
122 | } else { |
123 | LIST_LINK_TAIL(ads->input,qu); |
124 | adns_event(ads,0,0,0,0,0); |
125 | } |
126 | *query_r= qu; |
127 | } |