/* Copyright (C) 2015-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk4sock18.ctr */ /** @file dk4sock18.c The dk4sock18 module. */ #line 10 "dk4sock18.ctr" #include "dk4conf.h" #include "dk4sock.h" #include "dk4mem.h" #include "dk4maodd.h" #if !DK4_HAVE_GETADDRINFO #include "dk4rec24.h" #endif #include "dk4maiddus.h" #include "dk4unused.h" #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif #line 33 "dk4sock18.ctr" #if DK4_ON_WINDOWS #if DK4_HAVE_GETADDRINFO static dk4_socket_t dk4socket_wc_tcp_client_addresses( ADDRINFOW *raddrst, ADDRINFOW *laddrst, long secs, long usecs, dk4_er_t *erp ) { ADDRINFOW *ra; ADDRINFOW *la; dk4_socket_t back = INVALID_SOCKET; #line 53 "dk4sock18.ctr" ra = raddrst; while ((INVALID_SOCKET == back) && (NULL != ra)) { if (NULL != laddrst) { la = laddrst; while ((INVALID_SOCKET == back) && (NULL != la)) { if (la->ai_family == ra->ai_family) { #line 60 "dk4sock18.ctr" #line 61 "dk4sock18.ctr" #line 62 "dk4sock18.ctr" #line 63 "dk4sock18.ctr" back = dk4socket_tcp_client_for_addr( ra->ai_family, ra->ai_addr, ra->ai_addrlen, la->ai_addr, la->ai_addrlen, secs, usecs, erp ); if (INVALID_SOCKET != back) { la = NULL; ra = NULL; } } if (NULL != la) { la = la->ai_next; } } } else { back = dk4socket_tcp_client_for_addr( ra->ai_family, ra->ai_addr, ra->ai_addrlen, NULL, 0, secs, usecs, erp ); if (INVALID_SOCKET != back) { ra = NULL; } } if (NULL != ra) { ra = ra->ai_next; } } #line 85 "dk4sock18.ctr" return back; } #else #endif #endif dk4_socket_t dk4socket_wc_tcp_client_host_num_srv( #if DK4_ON_WINDOWS const wchar_t *hostname, const wchar_t *svcname, const wchar_t *lsvcname, long secs, long usecs, int nsrv, #else const wchar_t * DK4_ARG_UNUSED(hostname), const wchar_t * DK4_ARG_UNUSED(svcname), const wchar_t * DK4_ARG_UNUSED(lsvcname), long DK4_ARG_UNUSED(secs), long DK4_ARG_UNUSED(usecs), int DK4_ARG_UNUSED(nsrv), #endif dk4_er_t *erp ) { #if DK4_ON_WINDOWS #if DK4_HAVE_GETADDRINFO /* +++++ +getaddrinfo */ ADDRINFOW rhints; ADDRINFOW lhints; ADDRINFOW *raddrst = NULL; ADDRINFOW *laddrst = NULL; dk4_socket_t back = INVALID_SOCKET; int res; #line 125 "dk4sock18.ctr" #if DK4_USE_ASSERT assert(NULL != hostname); assert(NULL != svcname); #endif if ((NULL != hostname) && (NULL != svcname)) { DK4_MEMRES(&rhints, sizeof(rhints)); rhints.ai_family = AF_UNSPEC; rhints.ai_socktype = SOCK_STREAM; if (0 != nsrv) { rhints.ai_flags = AI_NUMERICSERV; } rhints.ai_protocol = 0; res = GetAddrInfoW(hostname, svcname, &rhints, &raddrst); if ((0 == res) && (NULL != raddrst)) { if (NULL != lsvcname) { DK4_MEMRES(&lhints, sizeof(lhints)); lhints.ai_family = AF_UNSPEC; lhints.ai_socktype = SOCK_STREAM; lhints.ai_flags = AI_PASSIVE; if (0 != nsrv) { lhints.ai_flags |= AI_NUMERICSERV; } lhints.ai_protocol = 0; res = GetAddrInfoW(NULL, lsvcname, &lhints, &laddrst); if ((0 == res) && (NULL != laddrst)) { back = dk4socket_wc_tcp_client_addresses( raddrst, laddrst, secs, usecs, erp ); if (NULL != laddrst) { FreeAddrInfoW(laddrst); } } else { /* ERROR: getaddrinfo failed */ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRLOC, res); } } else { back = dk4socket_wc_tcp_client_addresses( raddrst, NULL, secs, usecs, erp ); } } else { /* ERROR: getaddrinfo failed */ dk4error_set_idetails(erp, DK4_E_SOCKET_GETADDRINFO, res); } if (NULL != laddrst) { FreeAddrInfoW(laddrst); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 168 "dk4sock18.ctr" return back; /* ----- +getaddrinfo */ #else /* +++++ -getaddrinfo */ char cppt[48]; char cplp[48]; struct servent *serv = NULL; const wchar_t *endptr = NULL; dk4_socket_t back = INVALID_SOCKET; int res = 0; unsigned short rport = 0U; unsigned short lport = 0U; unsigned short iport = 0U; #if DK4_USE_ASSERT assert(NULL != hostname); assert(NULL != svcname); #endif if ((NULL != hostname) && (NULL != svcname)) { res = dk4ma_input_dk_dec_ushort(&rport, svcname, &endptr, 1, erp); if (0 == res) { if (0 != dk4recode_wchar_t_to_char(cppt, sizeof(cppt), svcname, erp)) { dk4socket_error_reset(); serv = getservbyname(cppt, NULL); if (NULL != serv) { iport = serv->s_port; dk4socket_swap_bytes_if_not_bigendian((void *)(&iport),sizeof(iport)); rport = (unsigned short)iport; } else { dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME); } } } if (0 != rport) { if (NULL != lsvcname) { endptr = NULL; res = dk4ma_input_dk_dec_ushort(&lport, lsvcname, &endptr, 1, erp); if (0 == res) { if (0 != dk4recode_wchar_t_to_char(cplp,sizeof(cplp),lsvcname,erp)) { dk4socket_error_reset(); serv = getservbyname(cplp, NULL); if (NULL != serv) { iport = serv->s_port; dk4socket_swap_bytes_if_not_bigendian( (void *)(&iport), sizeof(iport) ); lport = (unsigned short)iport; } else { dk4socket_error_report(erp, DK4_E_SOCKET_GETSERVBYNAME); } } else { /* ERROR: Text conversion failed, already reported */ } } if (0 != lport) { back = dk4socket_wc_tcp_client_host_port( hostname, rport, lport, secs, usecs, erp ); } } else { back = dk4socket_wc_tcp_client_host_port( hostname, rport, (unsigned short)0, secs, usecs, erp ); } } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } return back; /* ----- -getaddrinfo */ #endif #else DK4_UNUSED_ARG(hostname) DK4_UNUSED_ARG(svcname) DK4_UNUSED_ARG(lsvcname) DK4_UNUSED_ARG(secs) DK4_UNUSED_ARG(usecs) DK4_UNUSED_ARG(nsrv) dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return (DK4_SOCKET_RESULT_FAILED); #endif } dk4_socket_t dk4socket_wc_tcp_client_host_srv( const wchar_t *hostname, const wchar_t *svcname, const wchar_t *lsvcname, long secs, long usecs, dk4_er_t *erp ) { return ( dk4socket_wc_tcp_client_host_num_srv( hostname, svcname, lsvcname, secs, usecs, 0, erp ) ); } #if (DK4_HAVE_STRUCT_SOCKADDR_IN6) && (!(DK4_HAVE_GETADDRINFO)) /** used to initialize IPv6 address for binding local ports. */ static const IN6_ADDR dk4sock18_any6 = IN6ADDR_ANY_INIT ; #endif dk4_socket_t dk4socket_wc_tcp_client_host_port( #if DK4_ON_WINDOWS const wchar_t *hostname, unsigned short portno, unsigned short lportno, long secs, long usecs, #else const wchar_t * DK4_ARG_UNUSED(hostname), unsigned short DK4_ARG_UNUSED(portno), unsigned short DK4_ARG_UNUSED(lportno), long DK4_ARG_UNUSED(secs), long DK4_ARG_UNUSED(usecs), #endif dk4_er_t *erp ) { #if DK4_ON_WINDOWS #if DK4_HAVE_GETADDRINFO /* +++++ +getaddrinfo */ wchar_t rpnb[16*sizeof(dk4_um_t)]; wchar_t lpnb[16*sizeof(dk4_um_t)]; const size_t szrpbn = DK4_SIZEOF(rpnb,wchar_t); const size_t szlpnb = DK4_SIZEOF(lpnb,wchar_t); dk4_socket_t back = INVALID_SOCKET; int res; #line 307 "dk4sock18.ctr" #if DK4_USE_ASSERT assert(NULL != hostname); assert(0 < portno); #endif if ((NULL != hostname) && (0 < portno)) { res = dk4ma_write_decimal_unsigned(rpnb, szrpbn, (dk4_um_t)portno, 0, erp); if (0 != res) { if (0 < lportno) { res = dk4ma_write_decimal_unsigned(lpnb,szlpnb,(dk4_um_t)lportno,0,erp); if (0 != res) { back = dk4socket_wc_tcp_client_host_num_srv( hostname, rpnb, lpnb, secs, usecs, 1, erp ); } else { #line 321 "dk4sock18.ctr" } } else { back = dk4socket_wc_tcp_client_host_num_srv( hostname, rpnb, NULL, secs, usecs, 1, erp ); } } else { #line 328 "dk4sock18.ctr" } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 333 "dk4sock18.ctr" return back; /* ----- +getaddrinfo */ #else /* +++++ -getaddrinfo */ char hona[1040]; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 sr6; struct sockaddr_in6 sl6; #endif struct sockaddr_in sr4; struct sockaddr_in sl4; char **addrptr; struct hostent *hep; dk4_socket_t back = INVALID_SOCKET; #line 348 "dk4sock18.ctr" #if DK4_USE_ASSERT assert(NULL != hostname); assert(0 < portno); #endif if ((NULL != hostname) && (0 < portno)) { #line 353 "dk4sock18.ctr" if (0 != dk4recode_wchar_t_to_char(hona, sizeof(hona), hostname, erp)) { dk4socket_error_reset(); hep = gethostbyname(hona); #line 356 "dk4sock18.ctr" if (NULL != hep) { #line 357 "dk4sock18.ctr" if (NULL != hep->h_addr_list) { #line 358 "dk4sock18.ctr" switch (hep->h_addrtype) { case AF_INET : { if (4 == hep->h_length) { addrptr = hep->h_addr_list; while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { DK4_MEMRES(&sr4, sizeof(sr4)); sr4.sin_family = AF_INET; sr4.sin_port = dk4socket_htons(portno); DK4_MEMCPY(&(sr4.sin_addr), *addrptr, sizeof(IN_ADDR)); #line 368 "dk4sock18.ctr" if (0 != lportno) { DK4_MEMRES(&sl4, sizeof(sl4)); sl4.sin_family = AF_INET; sl4.sin_port = dk4socket_htons(lportno); sl4.sin_addr.s_addr = dk4socket_htonl(INADDR_ANY); #line 374 "dk4sock18.ctr" back = dk4socket_tcp_client_for_addr( AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), (struct sockaddr *)(&sl4), sizeof(sl4), secs, usecs, erp ); } else { back = dk4socket_tcp_client_for_addr( AF_INET, (struct sockaddr *)(&sr4), sizeof(sr4), NULL, 0, secs, usecs, erp ); } addrptr++; } } else { #line 388 "dk4sock18.ctr" dk4error_set_simple_error_code(erp, DK4_E_BUG); } } break; #if DK4_HAVE_STRUCT_SOCKADDR_IN6 case AF_INET6 : { if (16 == hep->h_length) { addrptr = hep->h_addr_list; while ((INVALID_SOCKET == back) && (NULL != *addrptr)) { DK4_MEMRES(&sr6, sizeof(sr6)); sr6.sin6_family = AF_INET6; sr6.sin6_port = dk4socket_htons(portno); DK4_MEMCPY(&(sr6.sin6_addr), *addrptr, sizeof(IN6_ADDR)); if (0 != lportno) { DK4_MEMRES(&sl6, sizeof(sl6)); sl6.sin6_family = AF_INET6; sl6.sin6_port = dk4socket_htons(lportno); DK4_MEMCPY(&(sl6.sin6_addr), &dk4sock18_any6, sizeof(IN6_ADDR)); back = dk4socket_tcp_client_for_addr( AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), (struct sockaddr *)(&sl6), sizeof(sl6), secs, usecs, erp ); } else { back = dk4socket_tcp_client_for_addr( AF_INET6, (struct sockaddr *)(&sr6), sizeof(sr6), NULL, 0, secs, usecs, erp ); } addrptr++; } } else { /* ERROR: Address length mismatch */ dk4error_set_simple_error_code(erp, DK4_E_BUG); } } break; #endif default : { /* ERROR: Unknown protocol */ dk4error_set_simple_error_code(erp, DK4_E_BUG); } break; } } else { #line 430 "dk4sock18.ctr" /* ERROR: List empty */ dk4error_set_simple_error_code(erp, DK4_E_BUG); } } else { #line 434 "dk4sock18.ctr" /* ERROR: Host not found */ dk4socket_error_report(erp, DK4_E_SOCKET_GETHOSTBYNAME); } } else { #line 438 "dk4sock18.ctr" /* ERROR: Failed to convert hostname to ASCII, already reported */ } } else { #line 441 "dk4sock18.ctr" dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } #line 444 "dk4sock18.ctr" return back; /* ----- -getaddrinfo */ #endif #else DK4_UNUSED_ARG(hostname) DK4_UNUSED_ARG(portno) DK4_UNUSED_ARG(lportno) DK4_UNUSED_ARG(secs) DK4_UNUSED_ARG(usecs) dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); return (DK4_SOCKET_RESULT_FAILED); #endif }