113498266Sopenharmony_ci/*************************************************************************** 213498266Sopenharmony_ci * _ _ ____ _ 313498266Sopenharmony_ci * Project ___| | | | _ \| | 413498266Sopenharmony_ci * / __| | | | |_) | | 513498266Sopenharmony_ci * | (__| |_| | _ <| |___ 613498266Sopenharmony_ci * \___|\___/|_| \_\_____| 713498266Sopenharmony_ci * 813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci * 1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci * 1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci * 1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci * KIND, either express or implied. 2013498266Sopenharmony_ci * 2113498266Sopenharmony_ci * SPDX-License-Identifier: curl 2213498266Sopenharmony_ci * 2313498266Sopenharmony_ci ***************************************************************************/ 2413498266Sopenharmony_ci 2513498266Sopenharmony_ci#include "curl_setup.h" 2613498266Sopenharmony_ci 2713498266Sopenharmony_ci#ifdef __AMIGA__ 2813498266Sopenharmony_ci 2913498266Sopenharmony_ci#include <curl/curl.h> 3013498266Sopenharmony_ci 3113498266Sopenharmony_ci#include "hostip.h" 3213498266Sopenharmony_ci#include "amigaos.h" 3313498266Sopenharmony_ci 3413498266Sopenharmony_ci#ifdef HAVE_PROTO_BSDSOCKET_H 3513498266Sopenharmony_ci# if defined(__amigaos4__) 3613498266Sopenharmony_ci# include <bsdsocket/socketbasetags.h> 3713498266Sopenharmony_ci# elif !defined(USE_AMISSL) 3813498266Sopenharmony_ci# include <amitcp/socketbasetags.h> 3913498266Sopenharmony_ci# endif 4013498266Sopenharmony_ci# ifdef __libnix__ 4113498266Sopenharmony_ci# include <stabs.h> 4213498266Sopenharmony_ci# endif 4313498266Sopenharmony_ci#endif 4413498266Sopenharmony_ci 4513498266Sopenharmony_ci/* The last #include files should be: */ 4613498266Sopenharmony_ci#include "curl_memory.h" 4713498266Sopenharmony_ci#include "memdebug.h" 4813498266Sopenharmony_ci 4913498266Sopenharmony_ci#ifdef HAVE_PROTO_BSDSOCKET_H 5013498266Sopenharmony_ci 5113498266Sopenharmony_ci#ifdef __amigaos4__ 5213498266Sopenharmony_ci/* 5313498266Sopenharmony_ci * AmigaOS 4.x specific code 5413498266Sopenharmony_ci */ 5513498266Sopenharmony_ci 5613498266Sopenharmony_ci/* 5713498266Sopenharmony_ci * hostip4.c - Curl_ipv4_resolve_r() replacement code 5813498266Sopenharmony_ci * 5913498266Sopenharmony_ci * Logic that needs to be considered are the following build cases: 6013498266Sopenharmony_ci * - newlib networking 6113498266Sopenharmony_ci * - clib2 networking 6213498266Sopenharmony_ci * - direct bsdsocket.library networking (usually AmiSSL builds) 6313498266Sopenharmony_ci * Each with the threaded resolver enabled or not. 6413498266Sopenharmony_ci * 6513498266Sopenharmony_ci * With the threaded resolver enabled, try to use gethostbyname_r() where 6613498266Sopenharmony_ci * available, otherwise (re)open bsdsocket.library and fallback to 6713498266Sopenharmony_ci * gethostbyname(). 6813498266Sopenharmony_ci */ 6913498266Sopenharmony_ci 7013498266Sopenharmony_ci#include <proto/bsdsocket.h> 7113498266Sopenharmony_ci 7213498266Sopenharmony_cistatic struct SocketIFace *__CurlISocket = NULL; 7313498266Sopenharmony_cistatic uint32 SocketFeatures = 0; 7413498266Sopenharmony_ci 7513498266Sopenharmony_ci#define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01 7613498266Sopenharmony_ci#define HAVE_BSDSOCKET_GETADDRINFO 0x02 7713498266Sopenharmony_ci 7813498266Sopenharmony_ciCURLcode Curl_amiga_init(void) 7913498266Sopenharmony_ci{ 8013498266Sopenharmony_ci struct SocketIFace *ISocket; 8113498266Sopenharmony_ci struct Library *base = OpenLibrary("bsdsocket.library", 4); 8213498266Sopenharmony_ci 8313498266Sopenharmony_ci if(base) { 8413498266Sopenharmony_ci ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); 8513498266Sopenharmony_ci if(ISocket) { 8613498266Sopenharmony_ci ULONG enabled = 0; 8713498266Sopenharmony_ci 8813498266Sopenharmony_ci SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE, 8913498266Sopenharmony_ci SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled, 9013498266Sopenharmony_ci TAG_DONE); 9113498266Sopenharmony_ci 9213498266Sopenharmony_ci if(enabled) { 9313498266Sopenharmony_ci SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R; 9413498266Sopenharmony_ci } 9513498266Sopenharmony_ci 9613498266Sopenharmony_ci __CurlISocket = ISocket; 9713498266Sopenharmony_ci 9813498266Sopenharmony_ci atexit(Curl_amiga_cleanup); 9913498266Sopenharmony_ci 10013498266Sopenharmony_ci return CURLE_OK; 10113498266Sopenharmony_ci } 10213498266Sopenharmony_ci CloseLibrary(base); 10313498266Sopenharmony_ci } 10413498266Sopenharmony_ci 10513498266Sopenharmony_ci return CURLE_FAILED_INIT; 10613498266Sopenharmony_ci} 10713498266Sopenharmony_ci 10813498266Sopenharmony_civoid Curl_amiga_cleanup(void) 10913498266Sopenharmony_ci{ 11013498266Sopenharmony_ci if(__CurlISocket) { 11113498266Sopenharmony_ci struct Library *base = __CurlISocket->Data.LibBase; 11213498266Sopenharmony_ci DropInterface((struct Interface *)__CurlISocket); 11313498266Sopenharmony_ci CloseLibrary(base); 11413498266Sopenharmony_ci __CurlISocket = NULL; 11513498266Sopenharmony_ci } 11613498266Sopenharmony_ci} 11713498266Sopenharmony_ci 11813498266Sopenharmony_ci#ifdef CURLRES_AMIGA 11913498266Sopenharmony_ci/* 12013498266Sopenharmony_ci * Because we need to handle the different cases in hostip4.c at run-time, 12113498266Sopenharmony_ci * not at compile-time, based on what was detected in Curl_amiga_init(), 12213498266Sopenharmony_ci * we replace it completely with our own as to not complicate the baseline 12313498266Sopenharmony_ci * code. Assumes malloc/calloc/free are thread safe because Curl_he2ai() 12413498266Sopenharmony_ci * allocates memory also. 12513498266Sopenharmony_ci */ 12613498266Sopenharmony_ci 12713498266Sopenharmony_cistruct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, 12813498266Sopenharmony_ci int port) 12913498266Sopenharmony_ci{ 13013498266Sopenharmony_ci struct Curl_addrinfo *ai = NULL; 13113498266Sopenharmony_ci struct hostent *h; 13213498266Sopenharmony_ci struct SocketIFace *ISocket = __CurlISocket; 13313498266Sopenharmony_ci 13413498266Sopenharmony_ci if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) { 13513498266Sopenharmony_ci LONG h_errnop = 0; 13613498266Sopenharmony_ci struct hostent *buf; 13713498266Sopenharmony_ci 13813498266Sopenharmony_ci buf = calloc(1, CURL_HOSTENT_SIZE); 13913498266Sopenharmony_ci if(buf) { 14013498266Sopenharmony_ci h = gethostbyname_r((STRPTR)hostname, buf, 14113498266Sopenharmony_ci (char *)buf + sizeof(struct hostent), 14213498266Sopenharmony_ci CURL_HOSTENT_SIZE - sizeof(struct hostent), 14313498266Sopenharmony_ci &h_errnop); 14413498266Sopenharmony_ci if(h) { 14513498266Sopenharmony_ci ai = Curl_he2ai(h, port); 14613498266Sopenharmony_ci } 14713498266Sopenharmony_ci free(buf); 14813498266Sopenharmony_ci } 14913498266Sopenharmony_ci } 15013498266Sopenharmony_ci else { 15113498266Sopenharmony_ci #ifdef CURLRES_THREADED 15213498266Sopenharmony_ci /* gethostbyname() is not thread safe, so we need to reopen bsdsocket 15313498266Sopenharmony_ci * on the thread's context 15413498266Sopenharmony_ci */ 15513498266Sopenharmony_ci struct Library *base = OpenLibrary("bsdsocket.library", 4); 15613498266Sopenharmony_ci if(base) { 15713498266Sopenharmony_ci ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); 15813498266Sopenharmony_ci if(ISocket) { 15913498266Sopenharmony_ci h = gethostbyname((STRPTR)hostname); 16013498266Sopenharmony_ci if(h) { 16113498266Sopenharmony_ci ai = Curl_he2ai(h, port); 16213498266Sopenharmony_ci } 16313498266Sopenharmony_ci DropInterface((struct Interface *)ISocket); 16413498266Sopenharmony_ci } 16513498266Sopenharmony_ci CloseLibrary(base); 16613498266Sopenharmony_ci } 16713498266Sopenharmony_ci #else 16813498266Sopenharmony_ci /* not using threaded resolver - safe to use this as-is */ 16913498266Sopenharmony_ci h = gethostbyname(hostname); 17013498266Sopenharmony_ci if(h) { 17113498266Sopenharmony_ci ai = Curl_he2ai(h, port); 17213498266Sopenharmony_ci } 17313498266Sopenharmony_ci #endif 17413498266Sopenharmony_ci } 17513498266Sopenharmony_ci 17613498266Sopenharmony_ci return ai; 17713498266Sopenharmony_ci} 17813498266Sopenharmony_ci#endif /* CURLRES_AMIGA */ 17913498266Sopenharmony_ci 18013498266Sopenharmony_ci#ifdef USE_AMISSL 18113498266Sopenharmony_ci#include <signal.h> 18213498266Sopenharmony_ciint Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds, 18313498266Sopenharmony_ci fd_set *errorfds, struct timeval *timeout) 18413498266Sopenharmony_ci{ 18513498266Sopenharmony_ci int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0); 18613498266Sopenharmony_ci /* Ensure Ctrl-C signal is actioned */ 18713498266Sopenharmony_ci if((r == -1) && (SOCKERRNO == EINTR)) 18813498266Sopenharmony_ci raise(SIGINT); 18913498266Sopenharmony_ci return r; 19013498266Sopenharmony_ci} 19113498266Sopenharmony_ci#endif /* USE_AMISSL */ 19213498266Sopenharmony_ci 19313498266Sopenharmony_ci#elif !defined(USE_AMISSL) /* __amigaos4__ */ 19413498266Sopenharmony_ci/* 19513498266Sopenharmony_ci * Amiga OS3 specific code 19613498266Sopenharmony_ci */ 19713498266Sopenharmony_ci 19813498266Sopenharmony_cistruct Library *SocketBase = NULL; 19913498266Sopenharmony_ciextern int errno, h_errno; 20013498266Sopenharmony_ci 20113498266Sopenharmony_ci#ifdef __libnix__ 20213498266Sopenharmony_civoid __request(const char *msg); 20313498266Sopenharmony_ci#else 20413498266Sopenharmony_ci# define __request(msg) Printf(msg "\n\a") 20513498266Sopenharmony_ci#endif 20613498266Sopenharmony_ci 20713498266Sopenharmony_civoid Curl_amiga_cleanup(void) 20813498266Sopenharmony_ci{ 20913498266Sopenharmony_ci if(SocketBase) { 21013498266Sopenharmony_ci CloseLibrary(SocketBase); 21113498266Sopenharmony_ci SocketBase = NULL; 21213498266Sopenharmony_ci } 21313498266Sopenharmony_ci} 21413498266Sopenharmony_ci 21513498266Sopenharmony_ciCURLcode Curl_amiga_init(void) 21613498266Sopenharmony_ci{ 21713498266Sopenharmony_ci if(!SocketBase) 21813498266Sopenharmony_ci SocketBase = OpenLibrary("bsdsocket.library", 4); 21913498266Sopenharmony_ci 22013498266Sopenharmony_ci if(!SocketBase) { 22113498266Sopenharmony_ci __request("No TCP/IP Stack running!"); 22213498266Sopenharmony_ci return CURLE_FAILED_INIT; 22313498266Sopenharmony_ci } 22413498266Sopenharmony_ci 22513498266Sopenharmony_ci if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno, 22613498266Sopenharmony_ci SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl", 22713498266Sopenharmony_ci TAG_DONE)) { 22813498266Sopenharmony_ci __request("SocketBaseTags ERROR"); 22913498266Sopenharmony_ci return CURLE_FAILED_INIT; 23013498266Sopenharmony_ci } 23113498266Sopenharmony_ci 23213498266Sopenharmony_ci#ifndef __libnix__ 23313498266Sopenharmony_ci atexit(Curl_amiga_cleanup); 23413498266Sopenharmony_ci#endif 23513498266Sopenharmony_ci 23613498266Sopenharmony_ci return CURLE_OK; 23713498266Sopenharmony_ci} 23813498266Sopenharmony_ci 23913498266Sopenharmony_ci#ifdef __libnix__ 24013498266Sopenharmony_ciADD2EXIT(Curl_amiga_cleanup, -50); 24113498266Sopenharmony_ci#endif 24213498266Sopenharmony_ci 24313498266Sopenharmony_ci#endif /* !USE_AMISSL */ 24413498266Sopenharmony_ci 24513498266Sopenharmony_ci#endif /* HAVE_PROTO_BSDSOCKET_H */ 24613498266Sopenharmony_ci 24713498266Sopenharmony_ci#endif /* __AMIGA__ */ 248