Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensetup.c
Go to the documentation of this file.
00001 /* 00002 * setup.c 00003 * - configuration file parsing 00004 * - management of global state 00005 */ 00006 /* 00007 * This file is 00008 * Copyright (C) 1997-1999 Ian Jackson <ian@davenant.greenend.org.uk> 00009 * 00010 * It is part of adns, which is 00011 * Copyright (C) 1997-2000 Ian Jackson <ian@davenant.greenend.org.uk> 00012 * Copyright (C) 1999-2000 Tony Finch <dot@dotat.at> 00013 * 00014 * This program is free software; you can redistribute it and/or modify 00015 * it under the terms of the GNU General Public License as published by 00016 * the Free Software Foundation; either version 2, or (at your option) 00017 * any later version. 00018 * 00019 * This program is distributed in the hope that it will be useful, 00020 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00022 * GNU General Public License for more details. 00023 * 00024 * You should have received a copy of the GNU General Public License 00025 * along with this program; if not, write to the Free Software Foundation, 00026 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00027 */ 00028 00029 #ifdef ADNS_JGAA_WIN32 00030 # include "adns_win32.h" 00031 # include <iphlpapi.h> 00032 #else 00033 # include <stdlib.h> 00034 # include <errno.h> 00035 # include <limits.h> 00036 # include <unistd.h> 00037 # include <fcntl.h> 00038 # include <netdb.h> 00039 # include <sys/socket.h> 00040 # include <netinet/in.h> 00041 # include <arpa/inet.h> 00042 #endif 00043 00044 #include "internal.h" 00045 00046 static void readconfig(adns_state ads, const char *filename, int warnmissing); 00047 00048 static void addserver(adns_state ads, struct in_addr addr) { 00049 int i; 00050 struct server *ss; 00051 00052 for (i=0; i<ads->nservers; i++) { 00053 if (ads->servers[i].addr.s_addr == addr.s_addr) { 00054 adns__debug(ads,-1,0,"duplicate nameserver %s ignored",inet_ntoa(addr)); 00055 return; 00056 } 00057 } 00058 00059 if (ads->nservers>=MAXSERVERS) { 00060 adns__diag(ads,-1,0,"too many nameservers, ignoring %s",inet_ntoa(addr)); 00061 return; 00062 } 00063 00064 ss= ads->servers+ads->nservers; 00065 ss->addr= addr; 00066 ads->nservers++; 00067 } 00068 00069 static void freesearchlist(adns_state ads) { 00070 if (ads->nsearchlist) free(*ads->searchlist); 00071 free(ads->searchlist); 00072 } 00073 00074 static void saveerr(adns_state ads, int en) { 00075 if (!ads->configerrno) ads->configerrno= en; 00076 } 00077 00078 static void configparseerr(adns_state ads, const char *fn, int lno, 00079 const char *fmt, ...) { 00080 va_list al; 00081 00082 saveerr(ads,EINVAL); 00083 if (!ads->diagfile || (ads->iflags & adns_if_noerrprint)) return; 00084 00085 if (lno==-1) fprintf(ads->diagfile,"adns: %s: ",fn); 00086 else fprintf(ads->diagfile,"adns: %s:%d: ",fn,lno); 00087 va_start(al,fmt); 00088 vfprintf(ads->diagfile,fmt,al); 00089 va_end(al); 00090 fputc('\n',ads->diagfile); 00091 } 00092 00093 static int nextword(const char **bufp_io, const char **word_r, int *l_r) { 00094 const char *p, *q; 00095 00096 p= *bufp_io; 00097 while (ctype_whitespace(*p)) p++; 00098 if (!*p) return 0; 00099 00100 q= p; 00101 while (*q && !ctype_whitespace(*q)) q++; 00102 00103 *l_r= q-p; 00104 *word_r= p; 00105 *bufp_io= q; 00106 00107 return 1; 00108 } 00109 00110 static void ccf_nameserver(adns_state ads, const char *fn, int lno, const char *buf) { 00111 struct in_addr ia; 00112 00113 if (!inet_aton(buf,&ia)) { 00114 configparseerr(ads,fn,lno,"invalid nameserver address `%s'",buf); 00115 return; 00116 } 00117 adns__debug(ads,-1,0,"using nameserver %s",inet_ntoa(ia)); 00118 addserver(ads,ia); 00119 } 00120 00121 static void ccf_search(adns_state ads, const char *fn, int lno, const char *buf) { 00122 const char *bufp, *word; 00123 char *newchars, **newptrs, **pp; 00124 int count, tl, l; 00125 00126 if (!buf) return; 00127 00128 bufp= buf; 00129 count= 0; 00130 tl= 0; 00131 while (nextword(&bufp,&word,&l)) { count++; tl += l+1; } 00132 00133 newptrs= malloc(sizeof(char*)*count); if (!newptrs) { saveerr(ads,errno); return; } 00134 newchars= malloc(tl); if (!newchars) { saveerr(ads,errno); free(newptrs); return; } 00135 00136 bufp= buf; 00137 pp= newptrs; 00138 while (nextword(&bufp,&word,&l)) { 00139 *pp++= newchars; 00140 memcpy(newchars,word,l); 00141 newchars += l; 00142 *newchars++ = 0; 00143 } 00144 00145 freesearchlist(ads); 00146 ads->nsearchlist= count; 00147 ads->searchlist= newptrs; 00148 } 00149 00150 static void ccf_sortlist(adns_state ads, const char *fn, int lno, const char *buf) { 00151 const char *word; 00152 char tbuf[200], *slash, *ep; 00153 struct in_addr base, mask; 00154 int l; 00155 unsigned long initial, baselocal; 00156 00157 if (!buf) return; 00158 00159 ads->nsortlist= 0; 00160 while (nextword(&buf,&word,&l)) { 00161 if (ads->nsortlist >= MAXSORTLIST) { 00162 adns__diag(ads,-1,0,"too many sortlist entries, ignoring %.*s onwards",l,word); 00163 return; 00164 } 00165 00166 if (l >= sizeof(tbuf)) { 00167 configparseerr(ads,fn,lno,"sortlist entry `%.*s' too long",l,word); 00168 continue; 00169 } 00170 00171 memcpy(tbuf,word,l); tbuf[l]= 0; 00172 slash= strchr(tbuf,'/'); 00173 if (slash) *slash++= 0; 00174 00175 if (!inet_aton(tbuf,&base)) { 00176 configparseerr(ads,fn,lno,"invalid address `%s' in sortlist",tbuf); 00177 continue; 00178 } 00179 00180 if (slash) { 00181 if (strchr(slash,'.')) { 00182 if (!inet_aton(slash,&mask)) { 00183 configparseerr(ads,fn,lno,"invalid mask `%s' in sortlist",slash); 00184 continue; 00185 } 00186 if (base.s_addr & ~mask.s_addr) { 00187 configparseerr(ads,fn,lno, 00188 "mask `%s' in sortlist overlaps address `%s'",slash,tbuf); 00189 continue; 00190 } 00191 } else { 00192 initial= strtoul(slash,&ep,10); 00193 if (*ep || initial>32) { 00194 configparseerr(ads,fn,lno,"mask length `%s' invalid",slash); 00195 continue; 00196 } 00197 mask.s_addr= htonl((0x0ffffffffUL) << (32-initial)); 00198 } 00199 } else { 00200 baselocal= ntohl(base.s_addr); 00201 if (!(baselocal & 0x080000000UL)) /* class A */ 00202 mask.s_addr= htonl(0x0ff000000UL); 00203 else if ((baselocal & 0x0c0000000UL) == 0x080000000UL) 00204 mask.s_addr= htonl(0x0ffff0000UL); /* class B */ 00205 else if ((baselocal & 0x0f0000000UL) == 0x0e0000000UL) 00206 mask.s_addr= htonl(0x0ff000000UL); /* class C */ 00207 else { 00208 configparseerr(ads,fn,lno, 00209 "network address `%s' in sortlist is not in classed ranges," 00210 " must specify mask explicitly", tbuf); 00211 continue; 00212 } 00213 } 00214 00215 ads->sortlist[ads->nsortlist].base= base; 00216 ads->sortlist[ads->nsortlist].mask= mask; 00217 ads->nsortlist++; 00218 } 00219 } 00220 00221 static void ccf_options(adns_state ads, const char *fn, int lno, const char *buf) { 00222 const char *word; 00223 char *ep; 00224 unsigned long v; 00225 int l; 00226 00227 if (!buf) return; 00228 00229 while (nextword(&buf,&word,&l)) { 00230 if (l==5 && !memcmp(word,"debug",5)) { 00231 ads->iflags |= adns_if_debug; 00232 continue; 00233 } 00234 if (l>=6 && !memcmp(word,"ndots:",6)) { 00235 v= strtoul(word+6,&ep,10); 00236 if (l==6 || ep != word+l || v > INT_MAX) { 00237 configparseerr(ads,fn,lno,"option `%.*s' malformed or has bad value",l,word); 00238 continue; 00239 } 00240 ads->searchndots= v; 00241 continue; 00242 } 00243 if (l>=12 && !memcmp(word,"adns_checkc:",12)) { 00244 if (!strcmp(word+12,"none")) { 00245 ads->iflags &= ~adns_if_checkc_freq; 00246 ads->iflags |= adns_if_checkc_entex; 00247 } else if (!strcmp(word+12,"entex")) { 00248 ads->iflags &= ~adns_if_checkc_freq; 00249 ads->iflags |= adns_if_checkc_entex; 00250 } else if (!strcmp(word+12,"freq")) { 00251 ads->iflags |= adns_if_checkc_freq; 00252 } else { 00253 configparseerr(ads,fn,lno, "option adns_checkc has bad value `%s' " 00254 "(must be none, entex or freq", word+12); 00255 } 00256 continue; 00257 } 00258 adns__diag(ads,-1,0,"%s:%d: unknown option `%.*s'", fn,lno, l,word); 00259 } 00260 } 00261 00262 static void ccf_clearnss(adns_state ads, const char *fn, int lno, const char *buf) { 00263 ads->nservers= 0; 00264 } 00265 00266 static void ccf_include(adns_state ads, const char *fn, int lno, const char *buf) { 00267 if (!*buf) { 00268 configparseerr(ads,fn,lno,"`include' directive with no filename"); 00269 return; 00270 } 00271 readconfig(ads,buf,1); 00272 } 00273 00274 static const struct configcommandinfo { 00275 const char *name; 00276 void (*fn)(adns_state ads, const char *fn, int lno, const char *buf); 00277 } configcommandinfos[]= { 00278 { "nameserver", ccf_nameserver }, 00279 { "domain", ccf_search }, 00280 { "search", ccf_search }, 00281 { "sortlist", ccf_sortlist }, 00282 { "options", ccf_options }, 00283 { "clearnameservers", ccf_clearnss }, 00284 { "include", ccf_include }, 00285 { 0 } 00286 }; 00287 00288 typedef union { 00289 FILE *file; 00290 const char *text; 00291 } getline_ctx; 00292 00293 static int gl_file(adns_state ads, getline_ctx *src_io, const char *filename, 00294 int lno, char *buf, int buflen) { 00295 FILE *file= src_io->file; 00296 int c, i; 00297 char *p; 00298 00299 p= buf; 00300 buflen--; 00301 i= 0; 00302 00303 for (;;) { /* loop over chars */ 00304 if (i == buflen) { 00305 adns__diag(ads,-1,0,"%s:%d: line too long, ignored",filename,lno); 00306 goto x_badline; 00307 } 00308 c= getc(file); 00309 if (!c) { 00310 adns__diag(ads,-1,0,"%s:%d: line contains nul, ignored",filename,lno); 00311 goto x_badline; 00312 } else if (c == '\n') { 00313 break; 00314 } else if (c == EOF) { 00315 if (ferror(file)) { 00316 saveerr(ads,errno); 00317 adns__diag(ads,-1,0,"%s:%d: read error: %s",filename,lno,strerror(errno)); 00318 return -1; 00319 } 00320 if (!i) return -1; 00321 break; 00322 } else { 00323 *p++= c; 00324 i++; 00325 } 00326 } 00327 00328 *p++= 0; 00329 return i; 00330 00331 x_badline: 00332 saveerr(ads,EINVAL); 00333 while ((c= getc(file)) != EOF && c != '\n'); 00334 return -2; 00335 } 00336 00337 static int gl_text(adns_state ads, getline_ctx *src_io, const char *filename, 00338 int lno, char *buf, int buflen) { 00339 const char *cp= src_io->text; 00340 int l; 00341 00342 if (!cp || !*cp) return -1; 00343 00344 if (*cp == ';' || *cp == '\n') cp++; 00345 l= strcspn(cp,";\n"); 00346 src_io->text = cp+l; 00347 00348 if (l >= buflen) { 00349 adns__diag(ads,-1,0,"%s:%d: line too long, ignored",filename,lno); 00350 saveerr(ads,EINVAL); 00351 return -2; 00352 } 00353 00354 memcpy(buf,cp,l); 00355 buf[l]= 0; 00356 return l; 00357 } 00358 00359 static void readconfiggeneric(adns_state ads, const char *filename, 00360 int (*getline)(adns_state ads, getline_ctx*, 00361 const char *filename, int lno, 00362 char *buf, int buflen), 00363 /* Returns >=0 for success, -1 for EOF or error 00364 * (error will have been reported), or -2 for 00365 * bad line was encountered, try again. 00366 */ 00367 getline_ctx gl_ctx) { 00368 char linebuf[2000], *p, *q; 00369 int lno, l, dirl; 00370 const struct configcommandinfo *ccip; 00371 00372 for (lno=1; 00373 (l= getline(ads,&gl_ctx, filename,lno, linebuf,sizeof(linebuf))) != -1; 00374 lno++) { 00375 if (l == -2) continue; 00376 while (l>0 && ctype_whitespace(linebuf[l-1])) l--; 00377 linebuf[l]= 0; 00378 p= linebuf; 00379 while (ctype_whitespace(*p)) p++; 00380 if (*p == '#' || !*p) continue; 00381 q= p; 00382 while (*q && !ctype_whitespace(*q)) q++; 00383 dirl= q-p; 00384 for (ccip=configcommandinfos; 00385 ccip->name && !((int)strlen(ccip->name)==dirl && !memcmp(ccip->name,p,q-p)); 00386 ccip++); 00387 if (!ccip->name) { 00388 adns__diag(ads,-1,0,"%s:%d: unknown configuration directive `%.*s'", 00389 filename,lno,q-p,p); 00390 continue; 00391 } 00392 while (ctype_whitespace(*q)) q++; 00393 ccip->fn(ads,filename,lno,q); 00394 } 00395 } 00396 00397 static const char *instrum_getenv(adns_state ads, const char *envvar) { 00398 const char *value; 00399 00400 value= getenv(envvar); 00401 if (!value) adns__debug(ads,-1,0,"environment variable %s not set",envvar); 00402 else adns__debug(ads,-1,0,"environment variable %s set to `%s'",envvar,value); 00403 return value; 00404 } 00405 00406 static void readconfig(adns_state ads, const char *filename, int warnmissing) { 00407 getline_ctx gl_ctx; 00408 00409 gl_ctx.file= fopen(filename,"r"); 00410 if (!gl_ctx.file) { 00411 if (errno == ENOENT) { 00412 if (warnmissing) 00413 adns__debug(ads,-1,0,"configuration file `%s' does not exist",filename); 00414 return; 00415 } 00416 saveerr(ads,errno); 00417 adns__diag(ads,-1,0,"cannot open configuration file `%s': %s", 00418 filename,strerror(errno)); 00419 return; 00420 } 00421 00422 readconfiggeneric(ads,filename,gl_file,gl_ctx); 00423 00424 fclose(gl_ctx.file); 00425 } 00426 00427 static void readconfigtext(adns_state ads, const char *text, const char *showname) { 00428 getline_ctx gl_ctx; 00429 00430 gl_ctx.text= text; 00431 readconfiggeneric(ads,showname,gl_text,gl_ctx); 00432 } 00433 00434 static void readconfigenv(adns_state ads, const char *envvar) { 00435 const char *filename; 00436 00437 if (ads->iflags & adns_if_noenv) { 00438 adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar); 00439 return; 00440 } 00441 filename= instrum_getenv(ads,envvar); 00442 if (filename) readconfig(ads,filename,1); 00443 } 00444 00445 static void readconfigenvtext(adns_state ads, const char *envvar) { 00446 const char *textdata; 00447 00448 if (ads->iflags & adns_if_noenv) { 00449 adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar); 00450 return; 00451 } 00452 textdata= instrum_getenv(ads,envvar); 00453 if (textdata) readconfigtext(ads,textdata,envvar); 00454 } 00455 00456 00457 int adns__setnonblock(adns_state ads, ADNS_SOCKET fd) { 00458 #ifdef ADNS_JGAA_WIN32 00459 unsigned long Val = 1; 00460 return (ioctlsocket (fd, FIONBIO, &Val) == 0) ? 0 : -1; 00461 #else 00462 int r; 00463 00464 r= fcntl(fd,F_GETFL,0); if (r<0) return errno; 00465 r |= O_NONBLOCK; 00466 r= fcntl(fd,F_SETFL,r); if (r<0) return errno; 00467 return 0; 00468 #endif 00469 } 00470 00471 static int init_begin(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { 00472 adns_state ads; 00473 00474 #ifdef ADNS_JGAA_WIN32 00475 WORD wVersionRequested = MAKEWORD( 2, 0 ); 00476 WSADATA wsaData; 00477 int err; 00478 #endif 00479 00480 ads= malloc(sizeof(*ads)); if (!ads) return errno; 00481 00482 ads->iflags= flags; 00483 ads->diagfile= diagfile; 00484 ads->configerrno= 0; 00485 LIST_INIT(ads->udpw); 00486 LIST_INIT(ads->tcpw); 00487 LIST_INIT(ads->childw); 00488 LIST_INIT(ads->output); 00489 ads->forallnext= 0; 00490 ads->nextid= 0x311f; 00491 ads->udpsocket= ads->tcpsocket= -1; 00492 adns__vbuf_init(&ads->tcpsend); 00493 adns__vbuf_init(&ads->tcprecv); 00494 ads->tcprecv_skip= 0; 00495 ads->nservers= ads->nsortlist= ads->nsearchlist= ads->tcpserver= 0; 00496 ads->searchndots= 1; 00497 ads->tcpstate= server_disconnected; 00498 timerclear(&ads->tcptimeout); 00499 ads->searchlist= 0; 00500 00501 #ifdef ADNS_JGAA_WIN32 00502 err= WSAStartup( wVersionRequested, &wsaData ); 00503 if ( err != 0 ) { 00504 if (ads->diagfile && ads->iflags & adns_if_debug) 00505 fprintf(ads->diagfile,"adns: WSAStartup() failed. \n"); 00506 return -1;} 00507 if (LOBYTE( wsaData.wVersion ) != 2 || 00508 HIBYTE( wsaData.wVersion ) != 0 ) { 00509 if (ads->diagfile && ads->iflags & adns_if_debug) 00510 fprintf(ads->diagfile,"adns: Need Winsock 2.0 or better!\n"); 00511 00512 WSACleanup(); 00513 return -1;} 00514 00515 /* The WinSock DLL is acceptable. Proceed. */ 00516 #endif 00517 00518 *ads_r= ads; 00519 00520 return 0; 00521 } 00522 00523 static int init_finish(adns_state ads) { 00524 struct in_addr ia; 00525 struct protoent *proto; 00526 int r; 00527 00528 if (!ads->nservers) { 00529 if (ads->diagfile && ads->iflags & adns_if_debug) 00530 fprintf(ads->diagfile,"adns: no nameservers, using localhost\n"); 00531 ia.s_addr= htonl(INADDR_LOOPBACK); 00532 addserver(ads,ia); 00533 } 00534 00535 proto= getprotobyname("udp"); if (!proto) { r= ENOPROTOOPT; goto x_free; } 00536 ADNS_CLEAR_ERRNO; 00537 ads->udpsocket= socket(AF_INET,SOCK_DGRAM,proto->p_proto); 00538 ADNS_CAPTURE_ERRNO; 00539 if (ads->udpsocket<0) { r= errno; goto x_free; } 00540 00541 r= adns__setnonblock(ads,ads->udpsocket); 00542 if (r) { r= errno; goto x_closeudp; } 00543 return 0; 00544 00545 x_closeudp: 00546 adns_socket_close(ads->udpsocket); 00547 x_free: 00548 free(ads); 00549 #ifdef ADNS_JGAA_WIN32 00550 WSACleanup(); 00551 #endif /* WIN32 */ 00552 return r; 00553 } 00554 00555 static void init_abort(adns_state ads) { 00556 if (ads->nsearchlist) { 00557 free(ads->searchlist[0]); 00558 free(ads->searchlist); 00559 } 00560 free(ads); 00561 #ifdef ADNS_JGAA_WIN32 00562 WSACleanup(); 00563 #endif /* WIN32 */ 00564 00565 } 00566 00567 int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) { 00568 adns_state ads; 00569 const char *res_options, *adns_res_options; 00570 int r; 00571 #ifdef ADNS_JGAA_WIN32 00572 #define SECURE_PATH_LEN (MAX_PATH - 64) 00573 char PathBuf[MAX_PATH]; 00574 struct in_addr addr; 00575 #define ADNS_PFIXED_INFO_BLEN (2048) 00576 PFIXED_INFO network_info = (PFIXED_INFO)_alloca(ADNS_PFIXED_INFO_BLEN); 00577 ULONG network_info_blen = ADNS_PFIXED_INFO_BLEN; 00578 DWORD network_info_result; 00579 PIP_ADDR_STRING pip; 00580 const char *network_err_str = ""; 00581 #endif 00582 00583 r= init_begin(&ads, flags, diagfile ? diagfile : stderr); 00584 if (r) return r; 00585 00586 res_options= instrum_getenv(ads,"RES_OPTIONS"); 00587 adns_res_options= instrum_getenv(ads,"ADNS_RES_OPTIONS"); 00588 ccf_options(ads,"RES_OPTIONS",-1,res_options); 00589 ccf_options(ads,"ADNS_RES_OPTIONS",-1,adns_res_options); 00590 00591 #ifdef ADNS_JGAA_WIN32 00592 GetWindowsDirectory(PathBuf, SECURE_PATH_LEN); 00593 strcat(PathBuf,"\\resolv.conf"); 00594 readconfig(ads,PathBuf,1); 00595 GetWindowsDirectory(PathBuf, SECURE_PATH_LEN); 00596 strcat(PathBuf,"\\resolv-adns.conf"); 00597 readconfig(ads,PathBuf,0); 00598 GetWindowsDirectory(PathBuf, SECURE_PATH_LEN); 00599 strcat(PathBuf,"\\System32\\Drivers\\etc\\resolv.conf"); 00600 readconfig(ads,PathBuf,1); 00601 GetWindowsDirectory(PathBuf, SECURE_PATH_LEN); 00602 strcat(PathBuf,"\\System32\\Drivers\\etc\\resolv-adns.conf"); 00603 readconfig(ads,PathBuf,0); 00604 network_info_result = GetNetworkParams(network_info, &network_info_blen); 00605 if (network_info_result != ERROR_SUCCESS){ 00606 switch(network_info_result) { 00607 case ERROR_BUFFER_OVERFLOW: network_err_str = "ERROR_BUFFER_OVERFLOW"; break; 00608 case ERROR_INVALID_PARAMETER: network_err_str = "ERROR_INVALID_PARAMETER"; break; 00609 case ERROR_NO_DATA: network_err_str = "ERROR_NO_DATA"; break; 00610 case ERROR_NOT_SUPPORTED: network_err_str = "ERROR_NOT_SUPPORTED"; break;} 00611 adns__diag(ads,-1,0,"GetNetworkParams() failed with error [%d] %s", 00612 network_info_result,network_err_str); 00613 } 00614 else { 00615 for(pip = &(network_info->DnsServerList); pip; pip = pip->Next) { 00616 addr.s_addr = inet_addr(pip->IpAddress.String); 00617 if ((addr.s_addr != INADDR_ANY) && (addr.s_addr != INADDR_NONE)) 00618 addserver(ads, addr); 00619 } 00620 } 00621 #else 00622 readconfig(ads,"/etc/resolv.conf",1); 00623 readconfig(ads,"/etc/resolv-adns.conf",0); 00624 #endif 00625 00626 readconfigenv(ads,"RES_CONF"); 00627 readconfigenv(ads,"ADNS_RES_CONF"); 00628 00629 readconfigenvtext(ads,"RES_CONF_TEXT"); 00630 readconfigenvtext(ads,"ADNS_RES_CONF_TEXT"); 00631 00632 ccf_options(ads,"RES_OPTIONS",-1,res_options); 00633 ccf_options(ads,"ADNS_RES_OPTIONS",-1,adns_res_options); 00634 00635 ccf_search(ads,"LOCALDOMAIN",-1,instrum_getenv(ads,"LOCALDOMAIN")); 00636 ccf_search(ads,"ADNS_LOCALDOMAIN",-1,instrum_getenv(ads,"ADNS_LOCALDOMAIN")); 00637 00638 if (ads->configerrno && ads->configerrno != EINVAL) { 00639 r= ads->configerrno; 00640 init_abort(ads); 00641 return r; 00642 } 00643 00644 r= init_finish(ads); 00645 if (r) return r; 00646 00647 adns__consistency(ads,0,cc_entex); 00648 *ads_r= ads; 00649 return 0; 00650 } 00651 00652 int adns_init_strcfg(adns_state *ads_r, adns_initflags flags, 00653 FILE *diagfile, const char *configtext) { 00654 adns_state ads; 00655 int r; 00656 00657 r= init_begin(&ads, flags, diagfile); if (r) return r; 00658 00659 readconfigtext(ads,configtext,"<supplied configuration text>"); 00660 if (ads->configerrno) { 00661 r= ads->configerrno; 00662 init_abort(ads); 00663 return r; 00664 } 00665 00666 r= init_finish(ads); if (r) return r; 00667 adns__consistency(ads,0,cc_entex); 00668 *ads_r= ads; 00669 return 0; 00670 } 00671 00672 00673 void adns_finish(adns_state ads) { 00674 adns__consistency(ads,0,cc_entex); 00675 for (;;) { 00676 if (ads->udpw.head) adns_cancel(ads->udpw.head); 00677 else if (ads->tcpw.head) adns_cancel(ads->tcpw.head); 00678 else if (ads->childw.head) adns_cancel(ads->childw.head); 00679 else if (ads->output.head) adns_cancel(ads->output.head); 00680 else break; 00681 } 00682 adns_socket_close(ads->udpsocket); 00683 if (ads->tcpsocket >= 0) adns_socket_close(ads->tcpsocket); 00684 adns__vbuf_free(&ads->tcpsend); 00685 adns__vbuf_free(&ads->tcprecv); 00686 freesearchlist(ads); 00687 free(ads); 00688 #ifdef ADNS_JGAA_WIN32 00689 WSACleanup(); 00690 #endif /* WIN32 */ 00691 00692 } 00693 00694 void adns_forallqueries_begin(adns_state ads) { 00695 adns__consistency(ads,0,cc_entex); 00696 ads->forallnext= 00697 ads->udpw.head ? ads->udpw.head : 00698 ads->tcpw.head ? ads->tcpw.head : 00699 ads->childw.head ? ads->childw.head : 00700 ads->output.head; 00701 } 00702 00703 adns_query adns_forallqueries_next(adns_state ads, void **context_r) { 00704 adns_query qu, nqu; 00705 00706 adns__consistency(ads,0,cc_entex); 00707 nqu= ads->forallnext; 00708 for (;;) { 00709 qu= nqu; 00710 if (!qu) return 0; 00711 if (qu->next) { 00712 nqu= qu->next; 00713 } else if (qu == ads->udpw.tail) { 00714 nqu= 00715 ads->tcpw.head ? ads->tcpw.head : 00716 ads->childw.head ? ads->childw.head : 00717 ads->output.head; 00718 } else if (qu == ads->tcpw.tail) { 00719 nqu= 00720 ads->childw.head ? ads->childw.head : 00721 ads->output.head; 00722 } else if (qu == ads->childw.tail) { 00723 nqu= ads->output.head; 00724 } else { 00725 nqu= 0; 00726 } 00727 if (!qu->parent) break; 00728 } 00729 ads->forallnext= nqu; 00730 if (context_r) *context_r= qu->ctx.ext; 00731 return qu; 00732 } 00733 00734 /* ReactOS addition */ 00735 void adns_addserver(adns_state ads, struct in_addr addr) { 00736 addserver(ads, addr); 00737 } Generated on Fri May 25 2012 04:16:06 for ReactOS by
1.7.6.1
|