netsupp.cpp

来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 1,244 行 · 第 1/3 页

CPP
1,244
字号
  if (h == NULL)    {      if (p != NULL)	{	  // There already is a suitable result	  *result = p;	  return 0;	}      switch (h_errno)	{	case HOST_NOT_FOUND:	  return EAI_NONAME;	case TRY_AGAIN:	  return EAI_AGAIN;	case NO_RECOVERY:	  return EAI_FAIL;	case NO_ADDRESS:	  return EAI_NODATA;	default:	  // EH!?	  return EAI_FAIL;	}    }  // convert the hostent to addrinfo  if (h->h_addrtype == AF_INET && (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC))    len = sizeof(struct sockaddr_in);# ifdef AF_INET6  else if (h->h_addrtype == AF_INET6 && (hint->ai_family == AF_INET6 ||					 hint->ai_family == AF_UNSPEC))    len = sizeof(struct sockaddr_in6);# endif  else    {      // We don't know what to do with these addresses      // Or gethostbyname returned information we don't want      if (p != NULL)	{	  *result = p;	  return 0;	}      return EAI_NODATA;    }  q->ai_flags = 0;  q->ai_family = h->h_addrtype;  q->ai_socktype = hint->ai_socktype;  q->ai_protocol = protonum;  q->ai_addrlen = len;  q->ai_addr = (sockaddr*)malloc(len);  if (q->ai_addr == NULL)    {      free(q);      freeaddrinfo(p);      return EAI_MEMORY;    }  if (h->h_addrtype == AF_INET)    {      struct sockaddr_in *sin = (sockaddr_in*)q->ai_addr;      sin->sin_family = AF_INET;# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN      sin->sin_len = sizeof(*sin);# endif      sin->sin_port = portnum;      memcpy(&sin->sin_addr, h->h_addr, h->h_length);    }# ifdef AF_INET6  else if (h->h_addrtype == AF_INET6)    {      struct sockaddr_in6 *sin6 = (sockaddr_in6*)q->ai_addr;      sin6->sin6_family = AF_INET6;#  ifdef HAVE_STRUCT_SOCKADDR_SA_LEN      sin6->sin6_len = sizeof(*sin6);#  endif      sin6->sin6_port = portnum;      sin6->sin6_flowinfo = 0;      memcpy(&sin6->sin6_addr, h->h_addr, h->h_length);      sin6->sin6_scope_id = 0;    }# endif  if (hint->ai_flags & AI_CANONNAME)    q->ai_canonname = strdup(h->h_name);  else    q->ai_canonname = NULL;  q->ai_next = p;  p = q;  // cycle through the rest of the hosts;  for (psa = (sockaddr**)h->h_addr_list + 1; *psa; psa++)    {      q = (addrinfo*)malloc(sizeof(*q));      if (q == NULL)	{	  freeaddrinfo(p);	  return EAI_MEMORY;	}      memcpy(q, p, sizeof(*q));      q->ai_addr = (sockaddr*)malloc(h->h_length);      if (q->ai_addr == NULL)	{	  freeaddrinfo(p);	  free(q);	  return EAI_MEMORY;	}      if (h->h_addrtype == AF_INET)	{	  struct sockaddr_in *sin = (sockaddr_in*)q->ai_addr;	  sin->sin_family = AF_INET;# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN	  sin->sin_len = sizeof(*sin);# endif	  sin->sin_port = portnum;	  memcpy(&sin->sin_addr, *psa, h->h_length);	}# ifdef AF_INET6      else if (h->h_addrtype == AF_INET6)	{	  struct sockaddr_in6 *sin6 = (sockaddr_in6*)q->ai_addr;	  sin6->sin6_family = AF_INET6;#  ifdef HAVE_STRUCT_SOCKADDR_SA_LEN	  sin6->sin6_len = sizeof(*sin6);#  endif	  sin6->sin6_port = portnum;	  sin6->sin6_flowinfo = 0;	  memcpy(&sin6->sin6_addr, *psa, h->h_length);	  sin6->sin6_scope_id = 0;	}# endif      if (q->ai_canonname != NULL)	q->ai_canonname = strdup(q->ai_canonname);      q->ai_next = p;      p = q;    }  *result = p;  return 0;			// Whew! Success!}static int make_inet(const char *name, int portnum, int protonum, struct addrinfo *p,		     const struct addrinfo *hint, struct addrinfo** result){  struct addrinfo *q;  do    {      // This 'do' is here just so that we can 'break' out of it      if (name != NULL)	{	  // first, try to use inet_pton before resolving	  // it will catch IP addresses given without having to go to lookup	  struct sockaddr_in *sin;	  struct in_addr in;# ifdef AF_INET6	  struct sockaddr_in6 *sin6;	  struct in6_addr in6;	  if (hint->ai_family == AF_INET6 || (hint->ai_family == AF_UNSPEC &&					      strchr(name, ':') != NULL))	    {	      // yes, this is IPv6	      if (inet_pton(AF_INET6, name, &in6) != 1)		{		  if (hint->ai_flags & AI_NUMERICHOST)		    {		      freeaddrinfo(p);		      return EAI_FAIL;		    }		  break;	// not a numeric host		}	      sin6 = (sockaddr_in6*)malloc(sizeof(*sin6));	      if (sin6 == NULL)		{		  freeaddrinfo(p);		  return EAI_MEMORY;		}	      memcpy(&sin6->sin6_addr, &in6, sizeof(in6));	      if (strchr(name, '%') != NULL)		{		  errno = 0;		  sin6->sin6_scope_id = strtoul(strchr(name, '%') + 1, NULL, 10);		  if (errno != 0)		    sin6->sin6_scope_id = 0; // no interface		}	      q = (addrinfo*)malloc(sizeof(*q));	      if (q == NULL)		{		  freeaddrinfo(p);		  free(sin6);		  return EAI_MEMORY;		}	      sin6->sin6_family = AF_INET6;#  ifdef HAVE_STRUCT_SOCKADDR_SA_LEN	      sin6->sin6_len = sizeof(*sin6);#  endif	      sin6->sin6_port = portnum;	      sin6->sin6_flowinfo = 0;	      q->ai_flags = 0;	      q->ai_family = AF_INET6;	      q->ai_socktype = hint->ai_socktype;	      q->ai_protocol = protonum;	      q->ai_addrlen = sizeof(*sin6);	      q->ai_canonname = NULL;	      q->ai_addr = (sockaddr*)sin6;	      q->ai_next = p;	      *result = q;	      return 0;		// success!	    }# endif // AF_INET6	  if (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC)	    {	      // This has to be IPv4	      if (inet_pton(AF_INET, name, &in) != 1)		{		  if (hint->ai_flags & AI_NUMERICHOST)		    {		      freeaddrinfo(p);		      return EAI_FAIL;	// invalid, I guess		    }		  break;	// not a numeric host, do lookup		}	      sin = (sockaddr_in*)malloc(sizeof(*sin));	      if (sin == NULL)		{		  freeaddrinfo(p);		  return EAI_MEMORY;		}	      q = (addrinfo*)malloc(sizeof(*q));	      if (q == NULL)		{		  freeaddrinfo(p);		  free(sin);		  return EAI_MEMORY;		}	      sin->sin_family = AF_INET;# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN	      sin->sin_len = sizeof(*sin);# endif	      sin->sin_port = portnum;	      sin->sin_addr = in;	      q->ai_flags = 0;	      q->ai_family = AF_INET;	      q->ai_socktype = hint->ai_socktype;	      q->ai_protocol = protonum;	      q->ai_addrlen = sizeof(*sin);	      q->ai_canonname = NULL;	      q->ai_addr = (sockaddr*)sin;	      q->ai_next = p;	      *result = q;	      return 0;	    }	  // Eh, what!?	  // One of the two above has to have matched	  kdError() << "I wasn't supposed to get here!";	}    } while (false);  // This means localhost  if (name == NULL)    {      struct sockaddr_in *sin = (sockaddr_in*)malloc(sizeof(*sin));# ifdef AF_INET6      struct sockaddr_in6 *sin6;# endif      if (hint->ai_family == AF_INET || hint->ai_family == AF_UNSPEC)	{	  if (sin == NULL)	    {	      free(sin);	      freeaddrinfo(p);	      return EAI_MEMORY;	    }	  // Do IPv4 first	  q = (addrinfo*)malloc(sizeof(*q));	  if (q == NULL)	    {	      free(sin);	      freeaddrinfo(p);	      return EAI_MEMORY;	    }	  sin->sin_family = AF_INET;# ifdef HAVE_STRUCT_SOCKADDR_SA_LEN	  sin->sin_len = sizeof(*sin);# endif	  sin->sin_port = portnum;	  if (hint->ai_flags & AI_PASSIVE)	    *(Q_UINT32*)&sin->sin_addr = INADDR_ANY;	  else	    *(Q_UINT32*)&sin->sin_addr = htonl(INADDR_LOOPBACK);	  q->ai_flags = 0;	  q->ai_family = AF_INET;	  q->ai_socktype = hint->ai_socktype;	  q->ai_protocol = protonum;	  q->ai_addrlen = sizeof(*sin);	  q->ai_canonname = NULL;	  q->ai_addr = (sockaddr*)sin;	  q->ai_next = p;	  p = q;	}# ifdef AF_INET6      // Try now IPv6      if (hint->ai_family == AF_INET6 || hint->ai_family == AF_UNSPEC)	{	  sin6 = (sockaddr_in6*)malloc(sizeof(*sin6));	  q = (addrinfo*)malloc(sizeof(*q));	  if (q == NULL || sin6 == NULL)	    {	      free(sin6);	      free(q);	      freeaddrinfo(p);	      return EAI_MEMORY;	    }	  sin6->sin6_family = AF_INET6;#  ifdef HAVE_STRUCT_SOCKADDR_SA_LEN	  sin6->sin6_len = sizeof(*sin6);#  endif	  sin6->sin6_port = portnum;	  sin6->sin6_flowinfo = 0;	  sin6->sin6_scope_id = 0;      // We don't want to use in6addr_loopback and in6addr_any	  memset(&sin6->sin6_addr, 0, sizeof(sin6->sin6_addr));	  if ((hint->ai_flags & AI_PASSIVE) == 0)	    ((char*)&sin6->sin6_addr)[15] = 1;	  q->ai_flags = 0;	  q->ai_family = AF_INET6;	  q->ai_socktype = hint->ai_socktype;	  q->ai_protocol = protonum;	  q->ai_addrlen = sizeof(*sin6);	  q->ai_canonname = NULL;	  q->ai_addr = (sockaddr*)sin6;	  q->ai_next = p;	  p = q;	}# endif // AF_INET6      *result = p;      return 0;			// success!    }  return inet_lookup(name, portnum, protonum, p, hint, result);}int getaddrinfo(const char *name, const char *serv,		const struct addrinfo* hint,		struct addrinfo** result){  unsigned short portnum;	// remember to store in network byte order  int protonum = IPPROTO_TCP;  const char *proto = "tcp";  struct addrinfo *p = NULL;  // Sanity checks:  if (hint == NULL || result == NULL)    return EAI_BADFLAGS;  if (hint->ai_family != AF_UNSPEC && hint->ai_family != AF_UNIX &&      hint->ai_family != AF_INET# ifdef AF_INET6      && hint->ai_family != AF_INET6# endif      )    return EAI_FAMILY;  if (hint->ai_socktype != 0 && hint->ai_socktype != SOCK_STREAM &&      hint->ai_socktype != SOCK_DGRAM)    return EAI_SOCKTYPE;  // Treat hostname of "*" as NULL, which means localhost  if (name != NULL && ((*name == '*' && name[1] == '\0') || *name == '\0'))    name = NULL;  // Treat service of "*" as NULL, which I guess means no port (0)  if (serv != NULL && ((*serv == '*' && serv[1] == '\0') || *serv == '\0'))    serv = NULL;  if (name == NULL && serv == NULL) // what the hell do you want?    return EAI_NONAME;  // This is just to make it easier  if (name != NULL && strcmp(name, "localhost") == 0)     name = NULL;  // First, check for a Unix socket  // family must be either AF_UNIX or AF_UNSPEC  // either of name or serv must be set, the other must be NULL or empty  if (hint->ai_family == AF_UNIX || hint->ai_family == AF_UNSPEC)    {      if (name != NULL && serv != NULL)	{

⌨️ 快捷键说明

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