• Patch: Elm ME+ 2.5 PLalpha51 -> Elm ME+ 2.5 PLalpha52 [4/7] (5/5)

    From Kari Hurtta@21:1/5 to All on Mon Jun 8 19:51:10 2020
    [continued from previous message]

    + struct cancel_data ** cancel_p /* May be NULL, used if dns lookup was cancelable */;
    + enum lookup_show_message show_message;
    + int * was_error_p /* Error message is shown if was_error_p != NULL */;
    + const char * s;
    +
    + {
    + int ret = 0;
    +
    + char ** res = *res_p;
    + size_t reslen = *reslen_p;
    +
    + struct hostent * he = NULL;
    + int check_error = 0;
    +
    + errno = 0;
    +
    + if (sockaddr_size < sizeof (sockaddr_ptr.sa->sa_family)) {
    + DPRINT(Debug,12,(&Debug,
    + "lookup_SOCKADDR_ptr: sockaddr size = %zu < sa_family size %zu\n",
    + sockaddr_size,sizeof (sockaddr_ptr.sa->sa_family)));
    + goto fail;
    +
    + } else {
    +
    + looking_up_msg_helper(cancel_p,show_message,s);
    +
    + switch (sockaddr_ptr.sa->sa_family) {
    + #if defined(I_NETINET_IN) && defined(I_ARPA_INET)
    + case AF_INET:
    +
    + if (sockaddr_size < sizeof (* (sockaddr_ptr.sin))) {
    + DPRINT(Debug,12,(&Debug,
    + "lookup_SOCKADDR_ptr: sockaddr size = %zu < sockaddr_sin size %zu\n",
    + sockaddr_size,sizeof (* (sockaddr_ptr.sin)))); + goto fail;
    + }
    +
    + he = gethostbyaddr((void *)&(sockaddr_ptr.sin->sin_addr),
    + sizeof (sockaddr_ptr.sin->sin_addr),
    + sockaddr_ptr.sin->sin_family);
    +
    + if (!he)
    + check_error = 1;
    + break;
    +
    + #ifdef HAVE_IN6
    + case AF_INET6:
    +
    + if (sockaddr_size < sizeof (* (sockaddr_ptr.sin6))) {
    + DPRINT(Debug,12,(&Debug,
    + "lookup_SOCKADDR_ptr: sockaddr size = %zu < sockaddr_sin6 size %zu\n",
    + sockaddr_size,sizeof (* (sockaddr_ptr.sin6))));
    + goto fail;
    + }
    +
    + he = gethostbyaddr((void *)&(sockaddr_ptr.sin6->sin6_addr),
    + sizeof (sockaddr_ptr.sin6->sin6_addr),
    + sockaddr_ptr.sin6->sin6_family);
    +
    + if (!he)
    + check_error = 1;
    +
    + break;
    + #endif
    + #endif
    + default:
    + DPRINT(Debug,12,(&Debug,
    + "lookup_SOCKADDR_ptr: Unsupported address family %d\n",
    + sockaddr_ptr.sa->sa_family));
    + break;
    + }
    +
    +
    + if (check_error) {
    + int err = errno;
    +
    + DPRINT(Debug,9,(&Debug,
    + "lookup_SOCKADDR_ptr: %s: h_errno=%d",
    + s ? s : "(addr)",h_errno));
    + if (err) {
    + DPRINT(Debug,9,(&Debug, " errno=%d (%s)",
    + err,strerror(err)));
    + }
    + DPRINT(Debug,9,(&Debug, "\n"));
    +
    + if (HOST_NOT_FOUND != h_errno &&
    + NO_DATA != h_errno &&
    + NO_RECOVERY != h_errno &&
    + EINTR == err && cancel_p && *cancel_p &&
    + is_canceled(*cancel_p)) {
    + DPRINT(Debug,9,(&Debug,
    + "lookup_SOCKADDR_ptr: %s: query canceled\n",
    + s ? s : "(addr)"));
    + goto fail;
    +
    + } else if (was_error_p) {
    +
    + switch(h_errno) {
    + case HOST_NOT_FOUND:
    + case NO_DATA:
    + if (s) {
    + lib_error(CATGETS(elm_msg_cat, MeSet,MeNoNameAddress,
    + "No name for address: %s"),
    + s);
    + *was_error_p = 1;
    + }
    + break;
    + case TRY_AGAIN:
    + if (s) {
    + if (err)
    + lib_error(CATGETS(elm_msg_cat,
    + MeSet,
    + MeLookErrno,
    + "Looking up %s: %s"),
    + s,strerror(err));
    + else
    + lib_error(CATGETS(elm_msg_cat, MeSet,MeTempNoNameAddress,
    + "Name for address %s is not yet found..."),
    + s);
    + *was_error_p = 1;
    +
    + }
    + break;
    + case NO_RECOVERY:
    + if (s) {
    + lib_error(CATGETS(elm_msg_cat, MeSet,MeNoRecoveryBadAddress,
    + "Looking up %s: No recovery; Bad address or refused query?"),
    + hostname);
    + *was_error_p = 1;
    + }
    + break;
    + default:
    + if (s) {
    + if (err)
    + lib_error(CATGETS(elm_msg_cat,
    + MeSet,
    + MeAddrNameError1,
    + "Failed to get name for address %s: %s"),
    + s,strerror(err));
    + else
    + lib_error(CATGETS(elm_msg_cat, MeSet,MeAddrNameError,
    + "Failed to get name for address %s"),
    + s);
    + *was_error_p = 1;
    + }
    + break;
    + }
    + }
    +
    + } else if (s) {
    + switch (show_message) {
    + case no_lookup_message:
    + break;
    + case show_lookup_message:
    + lib_transient(CATGETS(elm_msg_cat, MeSet,MeLookingUpOK,
    + "Looking up %s ... OK"),
    + s);
    + break;
    + }
    + }
    + }
    +
    + if (he) {
    + size_t count = 0;
    + size_t idx = 0;
    +
    + if (he->h_name)
    + count++;
    + if (he->h_aliases) {
    + size_t i;
    +
    + for (i = 0; he->h_aliases[i]; i++)
    + count++;
    + }
    +
    +
    + if (res) {
    + /* CLear previous data */
    +
    + size_t i;
    +
    + for (i = 0; i < reslen; i++) {
    + if (res[i]) {
    + free(res[i]);
    + res[i] = NULL;
    + }
    + }
    + }
    +
    +
    + res = safe_array_realloc(res,count+1,sizeof (res[0]));
    +
    + if (reslen < count+1) {
    + /* Clear rest */
    +
    + size_t i;
    +
    + for (i = reslen; i < count+1; i++) {
    + res[i] = NULL;
    + }
    + }
    +
    + #define ADD(s) do { if (idx >= count) { goto failx; } res[idx++] = safe_strdup(s); } while(0)
    +
    + if (he->h_name)
    + ADD(he->h_name);
    +
    + if (he->h_aliases) {
    + size_t i;
    +
    + for (i = 0; he->h_aliases[i]; i++) {
    + ADD(he->h_aliases[i]);
    + }
    + }
    +
    + #undef ADD
    +
    + failx:
    + DPRINT(Debug,12,(&Debug,
    + "lookup_SOCKADDR_ptr: %zu items\n",
    + idx));
    +
    + res = safe_array_realloc(res,idx+1,sizeof (res[0]));
    + res[idx] = NULL;
    +
    + reslen = idx;
    + ret = 1;
    +
    + }
    +
    + if (!ret) {
    + fail:
    + if (res) {
    + size_t i;
    +
    + for (i = 0; i < reslen; i++) {
    + if (res[i]) {
    + free(res[i]);
    + res[i] = NULL;
    + }
    + }
    +
    + if (res) {
    + free(res);
    + res = NULL;
    + }
    + }
    + reslen = 0;
    + }
    +
    +
    + *res_p = res;
    + *reslen_p = reslen ;
    +
    + DPRINT(Debug,12,(&Debug,
    + "lookup_SOCKADDR_ptr=%d length %zu",ret,reslen));
    +
    + if (res) {
    + size_t i;
    +
    + DPRINT(Debug,12,(&Debug," result %p",res));
    +
    + for (i = 0; i < reslen; i++) {
    + DPRINT(Debug,12,(&Debug,
    + "%c %Q",
    + i ? ',' : ':',
    + res[i]));
    +
    + }
    + }
    +
    + DPRINT(Debug,12,(&Debug,"\n"));
    +
    + return ret;
    + }
    +
    +
    + /* Return 1 if succedd, 0 on failure
    +
    + Check with
    + if (cancel_p && *cancel_p && is_canceled(*cancel_p))
    + if failed for cancelation
    +
    + (re)allocates (*res_p) array
    +
    + Caller must free (*res_p) array
    + */
    +
    +
    + int give_name_from_sockaddr(sockaddr_ptr,sockaddr_size,res_p,reslen_p,cancel_p,
    + show_message,was_error_p)
    + const union SOCKADDR_ptr sockaddr_ptr;
    + const size_t sockaddr_size;
    + char *** res_p;
    + size_t * reslen_p;
    + struct cancel_data ** cancel_p /* May be NULL, used if dns lookup was cancelable */;
    + enum lookup_show_message show_message;
    + int * was_error_p /* Error message is shown if was_error_p != NULL */;
    + {
    +
    + int ret = 0;
    + char ** res = *res_p;
    + size_t reslen = *reslen_p;
    +
    +
    +
    + enum addr_lookup_v alookup =
    + give_dt_enumerate_as_int(&address_lookup);
    +
    + char mybuffer[256];
    + const char * s = give_SOCKADDR_ptr_as_string(sockaddr_ptr,sockaddr_size, + mybuffer,sizeof mybuffer); +
    +
    +
    + DPRINT(Debug,12,(&Debug,
    + "give_name_from_sockaddr: %s: address-lookup=%d",
    + s ? s : "(addr)", alookup));
    + switch (alookup) {
    + case addr_lookup_normal:
    + DPRINT(Debug,12,(&Debug," addr_lookup_normal"));
    + break;
    + case addr_lookup_shared: /* RESERVED */
    + DPRINT(Debug,12,(&Debug," addr_lookup_shared"));
    + break;
    + case addr_lookup_gethostbyaddr:
    + DPRINT(Debug,12,(&Debug," addr_lookup_gethostbyaddr"));
    + break;
    + case addr_lookup_getnameinfo:
    + DPRINT(Debug,12,(&Debug," addr_lookup_getnameinfo"));
    + break;
    + case NUM_addr_lookup:
    + DPRINT(Debug,12,(&Debug," NUM_addr_lookup"));
    + break;
    + }
    + DPRINT(Debug,12,(&Debug,"\n"));
    +
    + switch (alookup) {
    + case addr_lookup_normal:
    + case addr_lookup_gethostbyaddr:
    + ret = lookup_SOCKADDR_ptr(sockaddr_ptr,sockaddr_size,&res,&reslen,cancel_p,
    + show_message,was_error_p,s);
    + break;
    + case addr_lookup_getnameinfo:
    + #ifdef HAVE_GETNAMEINFO
    + ret = lookupi_SOCKADDR_ptr(sockaddr_ptr,sockaddr_size,&res,&reslen,cancel_p,
    + show_message,was_error_p,s);
    +
    + #else
    + DPRINT(Debug,12,(&Debug,
    + "give_name_from_sockaddr: %s: getaddrinfo() not available.\n",
    + s ? s : "(addr)"));
    + #endif
    + break;
    + case addr_lookup_shared:
    + case NUM_addr_lookup: /* Not used */
    + break;
    + }
    +
    + *res_p = res;
    + *reslen_p = reslen ;
    +
    + DPRINT(Debug,12,(&Debug,
    + "give_name_from_sockaddr=%d %s length %zu",ret,s ? s : "(addr)",reslen));
    +
    + if (res) {
    + size_t i;
    +
    + DPRINT(Debug,12,(&Debug," result %p",res));
    +
    + for (i = 0; i < reslen; i++) {
    + DPRINT(Debug,12,(&Debug,
    + "%c %Q",
    + i ? ',' : ':',
    + res[i]));
    +
    + }
    + }
    +
    + DPRINT(Debug,12,(&Debug,"\n"));
    +
    + return ret;
    + }

    /* Increments refcount */
    struct service_entry * give_service_entry_can(hostname,flag,initial_tls,now, ***************
    *** 5143,5149 ****
    goto try_scope;
    }
    }
    ! #endif

    DPRINT(Debug,12,(&Debug,
    "get_ip: Unsuported scope %s on IP-address %s\n", --- 5750,5756 ----
    goto try_scope;
    }
    }
    ! #endif /* HAVE_NAMEINDEX */

    DPRINT(Debug,12,(&Debug,
    "get_ip: Unsuported scope %s on IP-address %s\n", ***************
    *** 5167,5178 ****
    "get_ip: address is %s (len %d)\n",
    body,len));

    ! #else
    DPRINT(Debug,12,(&Debug,
    "get_ip: Unsuported scope %s on IP-address %s\n",
    pos+1,val));
    goto fail_scope;
    ! #endif
    }

    if (inet_pton(AF_INET6,body,
    --- 5774,5785 ----
    "get_ip: address is %s (len %d)\n",
    body,len));

    ! #else /* HAVE_SCOPE */
    DPRINT(Debug,12,(&Debug,
    "get_ip: Unsuported scope %s on IP-address %s\n",
    pos+1,val));
    goto fail_scope;
    ! #endif /* not HAVE_SCOPE */
    }

    if (inet_pton(AF_INET6,body,
    ***************
    *** 5200,5206 ****

    #ifdef HAVE_SCOPE
    result->sin6.sin6_scope_id = scope;
    ! #endif

    DPRINT(Debug,12,(&Debug,
    "get_ip: Parsed %s as IPv6 address (inet_pton) from %s\n",
    --- 5807,5813 ----