⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ares_search.c

📁 最新rtlinux内核源码
💻 C
字号:
/* Copyright 1998 by the Massachusetts Institute of Technology. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting * documentation, and that the name of M.I.T. not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * M.I.T. makes no representations about the suitability of * this software for any purpose.  It is provided "as is" * without express or implied warranty. * * CHANGELOG: this file has been modified by Sergio Perez Alca駃z <serpeal@upvnet.upv.es>  *            Departamento de Inform醫ica de Sistemas y Computadores           *            Universidad Polit閏nica de Valencia                              *            Valencia (Spain)     *            Date: April 2003                                           * */#include "ares_private.h"struct search_query {  /* Arguments passed to ares_search */  ares_channel channel;  char *name;			/* copied into an allocated buffer */  int dnsclass;  int type;  ares_callback callback;  void *arg;  int status_as_is;		/* error status from trying as-is */  int next_domain;		/* next search domain to try */  int trying_as_is;		/* current query is for name as-is */};static void search_callback(void *arg, int status, unsigned char *abuf,			    int alen);static void end_squery(struct search_query *squery, int status,		       unsigned char *abuf, int alen);static int cat_domain(const char *name, const char *domain, char **s);static int single_domain(ares_channel channel, const char *name, char **s);void ares_search(ares_channel channel, const char *name, int dnsclass,		 int type, ares_callback callback, void *arg){  struct search_query *squery;  char *s;  const char *p;  int status, ndots;    /* If name only yields one domain to search, then we don't have   * to keep extra state, so just do an ares_query().   */  status = single_domain(channel, name, &s);  if (status != ARES_SUCCESS)    {      callback(arg, status, NULL, 0);      return;    }  if (s)    {      ares_query(channel, s, dnsclass, type, callback, arg);      free(s);      return;    }    /* Allocate a search_query structure to hold the state necessary for   * doing multiple lookups.   */  squery = malloc(sizeof(struct search_query));  if (!squery)    {      callback(arg, ARES_ENOMEM, NULL, 0);      return;    }  squery->channel = channel;  squery->name = strdup(name);  if(!squery->name)    {      free(squery);      callback(arg, ARES_ENOMEM, NULL, 0);      return;    }  squery->dnsclass = dnsclass;  squery->type = type;  squery->status_as_is = -1;  squery->callback = callback;  squery->arg = arg;    /* Count the number of dots in name. */  ndots = 0;  for (p = name; *p; p++)    {      if (*p == '.')	ndots++;    }    /* If ndots is at least the channel ndots threshold (usually 1),   * then we try the name as-is first.  Otherwise, we try the name   * as-is last.   */  if (ndots >= channel->ndots)    {      /* Try the name as-is first. */      squery->next_domain = 0;      squery->trying_as_is = 1;      ares_query(channel, name, dnsclass, type, search_callback, squery);    }  else    {      /* Try the name as-is last; start with the first search domain. */      squery->next_domain = 1;      squery->trying_as_is = 0;      status = cat_domain(name, channel->domains[0], &s);      if (status == ARES_SUCCESS)	{	  ares_query(channel, s, dnsclass, type, search_callback, squery);	  free(s);	}      else	callback(arg, status, NULL, 0);    }}static void search_callback(void *arg, int status, unsigned char *abuf,			    int alen){  struct search_query *squery = (struct search_query *) arg;  ares_channel channel = squery->channel;  char *s;    /* Stop searching unless we got a non-fatal error. */  if (status != ARES_ENODATA && status != ARES_ESERVFAIL      && status != ARES_ENOTFOUND)    end_squery(squery, status, abuf, alen);  else    {      /* Save the status if we were trying as-is. */      if (squery->trying_as_is)	squery->status_as_is = status;      if (squery->next_domain < channel->ndomains)	{	  /* Try the next domain. */	  status = cat_domain(squery->name,			      channel->domains[squery->next_domain], &s);	  if (status != ARES_SUCCESS)	    end_squery(squery, status, NULL, 0);	  else	    {	      squery->trying_as_is = 0;	      squery->next_domain++;	      ares_query(channel, s, squery->dnsclass, squery->type,			 search_callback, squery);	      free(s);	    }	}      else if (squery->status_as_is == -1)	{	  /* Try the name as-is at the end. */	  squery->trying_as_is = 1;	  ares_query(channel, squery->name, squery->dnsclass, squery->type,		     search_callback, squery);	}      else	end_squery(squery, squery->status_as_is, NULL, 0);    }}static void end_squery(struct search_query *squery, int status,		       unsigned char *abuf, int alen){  squery->callback(squery->arg, status, abuf, alen);  free(squery->name);  free(squery);}/* Concatenate two domains. */static int cat_domain(const char *name, const char *domain, char **s){  int nlen = strlen(name), dlen = strlen(domain);    *s = malloc(nlen + 1 + dlen + 1);  if (!*s)    return ARES_ENOMEM;  memcpy(*s, name, nlen);  (*s)[nlen] = '.';  memcpy(*s + nlen + 1, domain, dlen);  (*s)[nlen + 1 + dlen] = 0;  return ARES_SUCCESS;}/* Determine if this name only yields one query.  If it does, set *s to * the string we should query, in an allocated buffer.  If not, set *s * to NULL. */static int single_domain(ares_channel channel, const char *name, char **s){  int len = strlen(name);    /* If the name contains a trailing dot, then the single query is the name   * sans the trailing dot.   */  if (name[len - 1] == '.')    {      *s = strdup(name);      return (*s) ? ARES_SUCCESS : ARES_ENOMEM;    }    if (channel->flags & ARES_FLAG_NOSEARCH || channel->ndomains == 0)    {      /* No domain search to do; just try the name as-is. */      *s = strdup(name);      return (*s) ? ARES_SUCCESS : ARES_ENOMEM;    }    *s = NULL;  return ARES_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -