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 + -
显示快捷键?