📄 setup.c
字号:
char linebuf[2000], *p, *q;
int lno, l, dirl;
const struct configcommandinfo *ccip;
for (lno=1;
(l= getline(ads,&gl_ctx, filename,lno, linebuf,sizeof(linebuf))) != -1;
lno++) {
if (l == -2) continue;
while (l>0 && ctype_whitespace(linebuf[l-1])) l--;
linebuf[l]= 0;
p= linebuf;
while (ctype_whitespace(*p)) p++;
if (*p == '#' || !*p) continue;
q= p;
while (*q && !ctype_whitespace(*q)) q++;
dirl= q-p;
for (ccip=configcommandinfos;
ccip->name && !((int)strlen(ccip->name)==dirl && !memcmp(ccip->name,p,q-p));
ccip++);
if (!ccip->name) {
adns__diag(ads,-1,0,"%s:%d: unknown configuration directive `%.*s'",
filename,lno,q-p,p);
continue;
}
while (ctype_whitespace(*q)) q++;
ccip->fn(ads,filename,lno,q);
}
}
static const char *instrum_getenv(adns_state ads, const char *envvar) {
const char *value;
value= getenv(envvar);
if (!value) adns__debug(ads,-1,0,"environment variable %s not set",envvar);
else adns__debug(ads,-1,0,"environment variable %s set to `%s'",envvar,value);
return value;
}
static void readconfig(adns_state ads, const char *filename, int warnmissing) {
getline_ctx gl_ctx;
gl_ctx.file= fopen(filename,"r");
if (!gl_ctx.file) {
if (errno == ENOENT) {
if (warnmissing)
adns__debug(ads,-1,0,"configuration file `%s' does not exist",filename);
return;
}
saveerr(ads,errno);
adns__diag(ads,-1,0,"cannot open configuration file `%s': %s",
filename,strerror(errno));
return;
}
readconfiggeneric(ads,filename,gl_file,gl_ctx);
fclose(gl_ctx.file);
}
static void readconfigtext(adns_state ads, const char *text, const char *showname) {
getline_ctx gl_ctx;
gl_ctx.text= text;
readconfiggeneric(ads,showname,gl_text,gl_ctx);
}
static void readconfigenv(adns_state ads, const char *envvar) {
const char *filename;
if (ads->iflags & adns_if_noenv) {
adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar);
return;
}
filename= instrum_getenv(ads,envvar);
if (filename) readconfig(ads,filename,1);
}
static void readconfigenvtext(adns_state ads, const char *envvar) {
const char *textdata;
if (ads->iflags & adns_if_noenv) {
adns__debug(ads,-1,0,"not checking environment variable `%s'",envvar);
return;
}
textdata= instrum_getenv(ads,envvar);
if (textdata) readconfigtext(ads,textdata,envvar);
}
int adns__setnonblock(adns_state ads, ADNS_SOCKET fd) {
#ifdef ADNS_JGAA_WIN32
unsigned long Val = 1;
return (ioctlsocket (fd, FIONBIO, &Val) == 0) ? 0 : -1;
#else
int r;
r= fcntl(fd,F_GETFL,0); if (r<0) return errno;
r |= O_NONBLOCK;
r= fcntl(fd,F_SETFL,r); if (r<0) return errno;
return 0;
#endif
}
static int init_begin(adns_state *ads_r, adns_initflags flags, FILE *diagfile) {
adns_state ads;
#ifdef ADNS_JGAA_WIN32
WORD wVersionRequested = MAKEWORD( 2, 0 );
WSADATA wsaData;
int err;
#endif
ads= malloc(sizeof(*ads)); if (!ads) return errno;
ads->iflags= flags;
ads->diagfile= diagfile;
ads->configerrno= 0;
LIST_INIT(ads->udpw);
LIST_INIT(ads->tcpw);
LIST_INIT(ads->childw);
LIST_INIT(ads->output);
ads->forallnext= 0;
ads->nextid= 0x311f;
ads->udpsocket= ads->tcpsocket= -1;
adns__vbuf_init(&ads->tcpsend);
adns__vbuf_init(&ads->tcprecv);
ads->tcprecv_skip= 0;
ads->nservers= ads->nsortlist= ads->nsearchlist= ads->tcpserver= 0;
ads->searchndots= 1;
ads->tcpstate= server_disconnected;
timerclear(&ads->tcptimeout);
ads->searchlist= 0;
#ifdef ADNS_JGAA_WIN32
err= WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
if (ads->diagfile && ads->iflags & adns_if_debug)
fprintf(ads->diagfile,"adns: WSAStartup() failed. \n");
return -1;}
if (LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 0 ) {
if (ads->diagfile && ads->iflags & adns_if_debug)
fprintf(ads->diagfile,"adns: Need Winsock 2.0 or better!\n");
WSACleanup();
return -1;}
/* The WinSock DLL is acceptable. Proceed. */
#endif
*ads_r= ads;
return 0;
}
static int init_finish(adns_state ads) {
struct in_addr ia;
struct protoent *proto;
int r;
if (!ads->nservers) {
if (ads->diagfile && ads->iflags & adns_if_debug)
fprintf(ads->diagfile,"adns: no nameservers, using localhost\n");
ia.s_addr= htonl(INADDR_LOOPBACK);
addserver(ads,ia);
}
proto= getprotobyname("udp"); if (!proto) { r= ENOPROTOOPT; goto x_free; }
ADNS_CLEAR_ERRNO;
ads->udpsocket= socket(AF_INET,SOCK_DGRAM,proto->p_proto);
ADNS_CAPTURE_ERRNO;
if (ads->udpsocket<0) { r= errno; goto x_free; }
r= adns__setnonblock(ads,ads->udpsocket);
if (r) { r= errno; goto x_closeudp; }
return 0;
x_closeudp:
adns_socket_close(ads->udpsocket);
x_free:
free(ads);
#ifdef ADNS_JGAA_WIN32
WSACleanup();
#endif /* WIN32 */
return r;
}
static void init_abort(adns_state ads) {
if (ads->nsearchlist) {
free(ads->searchlist[0]);
free(ads->searchlist);
}
free(ads);
#ifdef ADNS_JGAA_WIN32
WSACleanup();
#endif /* WIN32 */
}
int adns_init(adns_state *ads_r, adns_initflags flags, FILE *diagfile) {
adns_state ads;
const char *res_options, *adns_res_options;
int r;
#ifdef ADNS_JGAA_WIN32
#define SECURE_PATH_LEN (MAX_PATH - 64)
char PathBuf[MAX_PATH];
struct in_addr addr;
#define ADNS_PFIXED_INFO_BLEN (2048)
PFIXED_INFO network_info = (PFIXED_INFO)alloca(ADNS_PFIXED_INFO_BLEN);
ULONG network_info_blen = ADNS_PFIXED_INFO_BLEN;
DWORD network_info_result;
PIP_ADDR_STRING pip;
const char *network_err_str = "";
#endif
r= init_begin(&ads, flags, diagfile ? diagfile : stderr);
if (r) return r;
res_options= instrum_getenv(ads,"RES_OPTIONS");
adns_res_options= instrum_getenv(ads,"ADNS_RES_OPTIONS");
ccf_options(ads,"RES_OPTIONS",-1,res_options);
ccf_options(ads,"ADNS_RES_OPTIONS",-1,adns_res_options);
#ifdef ADNS_JGAA_WIN32
GetWindowsDirectory(PathBuf, SECURE_PATH_LEN);
strcat(PathBuf,"\\resolv.conf");
readconfig(ads,PathBuf,1);
GetWindowsDirectory(PathBuf, SECURE_PATH_LEN);
strcat(PathBuf,"\\resolv-adns.conf");
readconfig(ads,PathBuf,0);
GetWindowsDirectory(PathBuf, SECURE_PATH_LEN);
strcat(PathBuf,"\\System32\\Drivers\\etc\\resolv.conf");
readconfig(ads,PathBuf,1);
GetWindowsDirectory(PathBuf, SECURE_PATH_LEN);
strcat(PathBuf,"\\System32\\Drivers\\etc\\resolv-adns.conf");
readconfig(ads,PathBuf,0);
network_info_result = GetNetworkParams(network_info, &network_info_blen);
if (network_info_result != ERROR_SUCCESS){
switch(network_info_result) {
case ERROR_BUFFER_OVERFLOW: network_err_str = "ERROR_BUFFER_OVERFLOW"; break;
case ERROR_INVALID_PARAMETER: network_err_str = "ERROR_INVALID_PARAMETER"; break;
case ERROR_NO_DATA: network_err_str = "ERROR_NO_DATA"; break;
case ERROR_NOT_SUPPORTED: network_err_str = "ERROR_NOT_SUPPORTED"; break;}
adns__diag(ads,-1,0,"GetNetworkParams() failed with error [%d] %s",
network_info_result,network_err_str);
}
else {
for(pip = &(network_info->DnsServerList); pip; pip = pip->Next) {
addr.s_addr = inet_addr(pip->IpAddress.String);
if ((addr.s_addr != INADDR_ANY) && (addr.s_addr != INADDR_NONE))
addserver(ads, addr);
}
}
#else
readconfig(ads,"/etc/resolv.conf",1);
readconfig(ads,"/etc/resolv-adns.conf",0);
#endif
readconfigenv(ads,"RES_CONF");
readconfigenv(ads,"ADNS_RES_CONF");
readconfigenvtext(ads,"RES_CONF_TEXT");
readconfigenvtext(ads,"ADNS_RES_CONF_TEXT");
ccf_options(ads,"RES_OPTIONS",-1,res_options);
ccf_options(ads,"ADNS_RES_OPTIONS",-1,adns_res_options);
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;
adns__consistency(ads,0,cc_entex);
*ads_r= ads;
return 0;
}
int adns_init_strcfg(adns_state *ads_r, adns_initflags flags,
FILE *diagfile, const char *configtext) {
adns_state ads;
int r;
r= init_begin(&ads, flags, diagfile); if (r) return r;
readconfigtext(ads,configtext,"<supplied configuration text>");
if (ads->configerrno) {
r= ads->configerrno;
init_abort(ads);
return r;
}
r= init_finish(ads); if (r) return r;
adns__consistency(ads,0,cc_entex);
*ads_r= ads;
return 0;
}
void adns_finish(adns_state ads) {
adns__consistency(ads,0,cc_entex);
for (;;) {
if (ads->udpw.head) adns_cancel(ads->udpw.head);
else if (ads->tcpw.head) adns_cancel(ads->tcpw.head);
else if (ads->childw.head) adns_cancel(ads->childw.head);
else if (ads->output.head) adns_cancel(ads->output.head);
else break;
}
adns_socket_close(ads->udpsocket);
if (ads->tcpsocket >= 0) adns_socket_close(ads->tcpsocket);
adns__vbuf_free(&ads->tcpsend);
adns__vbuf_free(&ads->tcprecv);
freesearchlist(ads);
free(ads);
#ifdef ADNS_JGAA_WIN32
WSACleanup();
#endif /* WIN32 */
}
void adns_forallqueries_begin(adns_state ads) {
adns__consistency(ads,0,cc_entex);
ads->forallnext=
ads->udpw.head ? ads->udpw.head :
ads->tcpw.head ? ads->tcpw.head :
ads->childw.head ? ads->childw.head :
ads->output.head;
}
adns_query adns_forallqueries_next(adns_state ads, void **context_r) {
adns_query qu, nqu;
adns__consistency(ads,0,cc_entex);
nqu= ads->forallnext;
for (;;) {
qu= nqu;
if (!qu) return 0;
if (qu->next) {
nqu= qu->next;
} else if (qu == ads->udpw.tail) {
nqu=
ads->tcpw.head ? ads->tcpw.head :
ads->childw.head ? ads->childw.head :
ads->output.head;
} else if (qu == ads->tcpw.tail) {
nqu=
ads->childw.head ? ads->childw.head :
ads->output.head;
} else if (qu == ads->childw.tail) {
nqu= ads->output.head;
} else {
nqu= 0;
}
if (!qu->parent) break;
}
ads->forallnext= nqu;
if (context_r) *context_r= qu->ctx.ext;
return qu;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -