| 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 | } |