From 32af6b2a02aa7e71b367b71a048bd2459e368c25 Mon Sep 17 00:00:00 2001 From: ian Date: Sun, 11 Apr 1999 21:54:26 +0000 Subject: [PATCH] Parse searchlist; beginnings of paying attention. --- src/internal.h | 15 ++++++++- src/query.c | 6 ++-- src/setup.c | 89 ++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 85 insertions(+), 25 deletions(-) diff --git a/src/internal.h b/src/internal.h index 9a5f23d..a71d9dc 100644 --- a/src/internal.h +++ b/src/internal.h @@ -178,6 +178,18 @@ struct adns__query { byte *cname_dgram; int cname_dglen, cname_begin; /* If non-0, has been allocated using . */ + + vbuf search_vb; + int search_origlen, search_pos, search_doneabs; + /* Used by the searching algorithm. The query domain in textual form + * is copied into the vbuf, and _origlen set to its length. Then + * we walk the searchlist, if we want to. _pos says where we are + * (next entry to try), and _doneabs says whether we've done the + * absolute query yet. If flags doesn't have adns_qf_search then + * the vbuf is initialised but empty and everything else is zero. + * + * fixme: actually implement this! + */ int id, flags, udpretries; int udpnextserver; @@ -247,7 +259,7 @@ struct adns__state { struct { adns_query head, tail; } timew, childw, output; int nextid, udpsocket, tcpsocket; vbuf tcpsend, tcprecv; - int nservers, nsortlist, tcpserver; + int nservers, nsortlist, nsearchlist, tcpserver; enum adns__tcpstate { server_disconnected, server_connecting, server_ok } tcpstate; struct timeval tcptimeout; struct sigaction stdsigpipe; @@ -258,6 +270,7 @@ struct adns__state { struct sortlist { struct in_addr base, mask; } sortlist[MAXSORTLIST]; + char **searchlist; }; /* From setup.c: */ diff --git a/src/query.c b/src/query.c index 666fdd7..f710d3e 100644 --- a/src/query.c +++ b/src/query.c @@ -113,7 +113,7 @@ int adns_submit(adns_state ads, adns_query *query_r) { qcontext ctx; int id, r, ol; - vbuf vb; + vbuf vb, search_vb; adns_status stat; const typeinfo *typei; struct timeval now; @@ -131,9 +131,9 @@ int adns_submit(adns_state ads, adns__vbuf_init(&vb); ol= strlen(owner); - if (ol<=1 || ol>DNS_MAXDOMAIN+1) { stat= adns_s_querydomaintoolong; goto xit; } + if (ol>DNS_MAXDOMAIN+1) { stat= adns_s_querydomaintoolong; goto xit; } - if (owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; } + if (ol>=2 && owner[ol-1]=='.' && owner[ol-2]!='\\') { flags &= ~adns_qf_search; ol--; } stat= adns__mkquery(ads,&vb,&id, owner,ol, typei,flags); diff --git a/src/setup.c b/src/setup.c index 137d22b..26a5cff 100644 --- a/src/setup.c +++ b/src/setup.c @@ -74,6 +74,23 @@ static void configparseerr(adns_state ads, const char *fn, int lno, fputc('\n',ads->diagfile); } +static int nextword(const char **bufp_io, const char **word_r, int *l_r) { + const char *p, *q; + + p= *bufp_io; + while (ctype_whitespace(*p)) p++; + if (!*p) return 0; + + q= p; + while (*q && !ctype_whitespace(*q)) q++; + + *l_r= q-p; + *word_r= p; + *bufp_io= q; + + return 1; +} + static void ccf_nameserver(adns_state ads, const char *fn, int lno, const char *buf) { struct in_addr ia; @@ -86,42 +103,57 @@ static void ccf_nameserver(adns_state ads, const char *fn, int lno, const char * } static void ccf_search(adns_state ads, const char *fn, int lno, const char *buf) { + const char *bufp, *word; + char *newchars, **newptrs, **pp; + int count, tl, l; + if (!buf) return; - adns__diag(ads,-1,0,"warning - `search' ignored fixme"); + + bufp= buf; + count= 0; + tl= 0; + while (nextword(&bufp,&word,&l)) { count++; tl += l+1; } + + newptrs= malloc(sizeof(char*)*count); if (!newptrs) { saveerr(ads,errno); return; } + newchars= malloc(tl); if (!newchars) { saveerr(ads,errno); free(newptrs); return; } + + bufp= buf; + pp= newptrs; + while (nextword(&bufp,&word,&l)) { + *pp++= newchars; + memcpy(newchars,word,l); + newchars += l; + *newchars++ = 0; + } + + free(ads->searchlist); + ads->nsearchlist= count; + ads->searchlist= newptrs; + /* fixme: actually pay attention */ } -static void ccf_sortlist(adns_state ads, const char *fn, int lno, const char *bufp) { - const char *p, *q; +static void ccf_sortlist(adns_state ads, const char *fn, int lno, const char *buf) { + const char *word; char tbuf[200], *slash, *ep; struct in_addr base, mask; int l; unsigned long initial, baselocal; + if (!buf) return; + ads->nsortlist= 0; - if (!bufp) return; - - for (;;) { - while (ctype_whitespace(*bufp)) bufp++; - if (!*bufp) return; - - q= bufp; - while (*q && !ctype_whitespace(*q)) q++; - - p= bufp; - l= q-p; - bufp= q; - + while (nextword(&buf,&word,&l)) { if (ads->nsortlist >= MAXSORTLIST) { - adns__diag(ads,-1,0,"too many sortlist entries, ignoring %.*s onwards",l,p); + adns__diag(ads,-1,0,"too many sortlist entries, ignoring %.*s onwards",l,word); return; } if (l >= sizeof(tbuf)) { - configparseerr(ads,fn,lno,"sortlist entry `%.*s' too long",l,p); + configparseerr(ads,fn,lno,"sortlist entry `%.*s' too long",l,word); continue; } - memcpy(tbuf,p,l); + memcpy(tbuf,word,l); slash= strchr(tbuf,'/'); if (slash) *slash++= 0; @@ -393,8 +425,9 @@ static int init_begin(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { ads->udpsocket= ads->tcpsocket= -1; adns__vbuf_init(&ads->tcpsend); adns__vbuf_init(&ads->tcprecv); - ads->nservers= ads->nsortlist= ads->tcpserver= 0; + ads->nservers= ads->nsortlist= ads->nsearchlist= ads->tcpserver= 0; ads->tcpstate= server_disconnected; + ads->searchlist= 0; timerclear(&ads->tcptimeout); *ads_r= ads; @@ -429,6 +462,14 @@ static int init_finish(adns_state ads) { return r; } +static void init_abort(adns_state ads) { + if (ads->nsearchlist) { + free(ads->searchlist[0]); + free(ads->searchlist); + } + free(ads); +} + int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { adns_state ads; const char *res_options, *adns_res_options; @@ -455,6 +496,12 @@ int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { ccf_search(ads,"LOCALDOMAIN",-1,instrum_getenv(ads,"LOCALDOMAIN")); ccf_search(ads,"ADNS_LOCALDOMAIN",-1,instrum_getenv(ads,"ADNS_LOCALDOMAIN")); + if (ads->configerrno && ads->configerrno != EINVAL) { + r= ads->configerrno; + init_abort(ads); + return r; + } + r= init_finish(ads); if (r) return r; @@ -472,7 +519,7 @@ int adns_init_strcfg(adns_state *ads_r, adns_initflags flags, readconfigtext(ads,configtext,""); if (ads->configerrno) { r= ads->configerrno; - free(ads); + init_abort(ads); return r; } -- 2.30.2