/* * Unhook signal-handlers and raise() signals we caught. */ int _sock_sig_restore (void) { int i; if (signal_depth == 0 || --signal_depth > 0) return (0); _sock_stop_timer(); for (i = 0; i < DIM(sig_tab); i++) { int sig = sig_tab[i].sig_num; #if (USE_SIGMASK) sigset_t pending, new_set; if (sigpending(&pending) == 0 && sigismember(&pending,sig)) { /* The signal became pending while we blocked it. * I.e. ^C was pressed, so act on it. */ sigemptyset (&new_set); sigaddset (&new_set, sig); SOCK_DEBUGF ((", raising %s", sig_tab[i].sig_name)); SOCK_ENTER_SCOPE(); sigprocmask (SIG_UNBLOCK, &new_set, NULL); SOCK_LEAVE_SCOPE(); } #else signal (sig, sig_tab[i].old); if (!sig_tab[i].caught) continue; sig_tab[i].caught = FALSE; if (sig_tab[i].exit && (sig_tab[i].old == SIG_DFL || sig_tab[i].old == SIG_IGN || sig_tab[i].old == sig_handler_watt)) { char buf[30]; strcpy (buf, "\nTerminating on "); strcat (buf, sig_tab[i].sig_name); sock_sig_exit (buf, sig); /* no return */ } SOCK_DEBUGF ((", raising %s", sig_tab[i].sig_name)); SOCK_ENTER_SCOPE(); raise (sig); SOCK_LEAVE_SCOPE(); return (-1); #endif } return (0); }
/* * Return a 'struct hostent *' for an address. */ struct hostent *W32_CALL gethostbyaddr (const char *addr_name, int len, int type) { struct _hostent h; SOCK_DEBUGF (("\ngethostbyaddr: %s", (type == AF_INET && addr_name) ? inet_ntoa(*(struct in_addr*)addr_name) : (type == AF_INET6 && addr_name) ? _inet6_ntoa(addr_name) : "")); #if defined(USE_IPV6) if (type == AF_INET6 && len == sizeof(struct in6_addr)) { struct hostent *he; SOCK_ENTER_SCOPE(); he = gethostbyaddr6 (addr_name); SOCK_LEAVE_SCOPE(); return (he); } #endif if (gethostbyaddr_internal (addr_name, len, type, &h)) { SOCK_DEBUGF ((" `%s'", h.h_name)); if (!did_lookup) SOCK_DEBUGF ((", %s", h.h_timeout ? "cached" : "hosts-file")); return fill_hostent (&h); } SOCK_DEBUGF ((" failed (%s) ", did_lookup ? dom_strerror(dom_errno) : hstrerror(h_errno))); return (NULL); }
/* * AI_V4MAPPED + AF_INET6 * If no IPv6 address then a query for IPv4 and map returned values. * * AI_ALL + AI_V4MAPPED + AF_INET6 * Return IPv6 and IPv4 mapped. * * AI_ADDRCONFIG * Only return IPv6 / IPv4 address if there is an interface of that * type active. */ struct hostent * W32_CALL getipnodebyname (const char *name, int af, int flags, int *error) { struct hostent *he1 = NULL; struct hostent *he2 = NULL; struct in_addr in4; struct in6_addr in6; BOOL have_v4 = TRUE, have_v6 = TRUE; BOOL v4 = FALSE, v6 = FALSE; int tmp_err; SOCK_DEBUGF (("\ngetipnodebyname: %s ", name)); /* If we care about active interfaces then check. */ if (flags & AI_ADDRCONFIG) scan_interface (&have_v4, &have_v6); /* Check for literal address. */ v4 = inet_pton (AF_INET, name, &in4); if (!v4) v6 = inet_pton (AF_INET6, name, &in6); /* Impossible combination? */ if ((af == AF_INET6 && !(flags & AI_V4MAPPED) && v4) || (af == AF_INET && v6) || (!have_v4 && v4) || (!have_v6 && v6) || (!have_v4 && af == AF_INET) || ((!have_v6 && af == AF_INET6) && ((flags & AI_V4MAPPED) && have_v4)) || !(flags & AI_V4MAPPED)) { *error = HOST_NOT_FOUND; return (NULL); } /* Literal address? */ if (v4 || v6) { struct hostent he; char *addr_list[2]; char *aliases[1]; he.h_name = (char*) name; he.h_addr_list = addr_list; he.h_addr_list[0] = (v4 ? (char*)&in4 : (char*)&in6); he.h_addr_list[1] = NULL; he.h_aliases = aliases; he.h_aliases[0] = NULL; he.h_length = (v4 ? INADDRSZ : IN6ADDRSZ); he.h_addrtype = (v4 ? AF_INET : AF_INET6); return copyandmerge (&he, NULL, af, error); } tmp_err = NO_RECOVERY; if (have_v6 && af == AF_INET6) { #if defined(USE_IPV6) he1 = gethostbyname6 (name); #else he1 = NULL; #endif if (!he1) tmp_err = HOST_NOT_FOUND; } if (have_v4 && (af == AF_INET || (af == AF_INET6 && (flags & AI_V4MAPPED) && (!he1 || (flags & AI_ALL))))) { SOCK_ENTER_SCOPE(); he2 = gethostbyname (name); SOCK_LEAVE_SCOPE(); if (!he2 || !he1) { *error = HOST_NOT_FOUND; return (NULL); } } else *error = tmp_err; return copyandmerge (he1, he2, af, error); }
struct hostent * W32_CALL getipnodebyaddr (const void *src, size_t len, int af, int *error) { struct hostent *he1, *he2; const BYTE *cp = (const BYTE*) src; SOCK_DEBUGF (("\ngetipnodebyaddr: ")); if (!src) { *error = NO_RECOVERY; return (NULL); } switch (af) { case AF_INET: if (len < INADDRSZ) { *error = NO_RECOVERY; return (NULL); } break; #if defined(USE_IPV6) case AF_INET6: if (len < IN6ADDRSZ) { *error = NO_RECOVERY; return (NULL); } break; #endif default: *error = NO_RECOVERY; return (NULL); } /* Look up IPv4 and IPv4 mapped/compatible addresses. */ if ((af == AF_INET6 && IN6_IS_ADDR_V4COMPAT(cp)) || (af == AF_INET6 && IN6_IS_ADDR_V4MAPPED(cp)) || (af == AF_INET)) { if (af == AF_INET6) cp += 12; SOCK_ENTER_SCOPE(); he1 = gethostbyaddr ((const char*)cp, 4, AF_INET); SOCK_LEAVE_SCOPE(); if (af == AF_INET) goto ret_copy; /* Convert from AF_INET to AF_INET6. */ he2 = copyandmerge (he1, NULL, af, error); if (he2) { memcpy (he2->h_addr, src, len); /* Restore original address */ SOCK_DEBUGF (("%s", af == AF_INET ? inet_ntoa(*(struct in_addr*)&he2->h_addr) : _inet6_ntoa(he2->h_addr))); } return (he2); } he1 = gethostbyaddr (src, len, AF_INET6); /* Lookup IPv6 address */ ret_copy: if (!he1) { *error = HOST_NOT_FOUND; return (NULL); } return copyandmerge (he1, NULL, af, error); }