diff options
-rw-r--r-- | lib/amigaos.c | 158 | ||||
-rw-r--r-- | lib/amigaos.h | 9 | ||||
-rw-r--r-- | lib/curl_setup.h | 12 | ||||
-rw-r--r-- | lib/easy.c | 2 | ||||
-rw-r--r-- | lib/hostip4.c | 6 |
5 files changed, 170 insertions, 17 deletions
diff --git a/lib/amigaos.c b/lib/amigaos.c index d26cd1da1..dcc5316f0 100644 --- a/lib/amigaos.c +++ b/lib/amigaos.c @@ -25,8 +25,14 @@ #include "curl_setup.h" #ifdef __AMIGA__ -# include "amigaos.h" -# if defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) + +#include "hostip.h" +#include "amigaos.h" + +#ifdef HAVE_PROTO_BSDSOCKET_H +# if defined(__amigaos4__) +# include <bsdsocket/socketbasetags.h> +# elif !defined(USE_AMISSL) # include <amitcp/socketbasetags.h> # endif # ifdef __libnix__ @@ -38,9 +44,136 @@ #include "curl_memory.h" #include "memdebug.h" -#ifdef __AMIGA__ +#ifdef HAVE_PROTO_BSDSOCKET_H #ifdef __amigaos4__ +/* + * AmigaOS 4.x specific code + */ + +/* + * hostip4.c - Curl_ipv4_resolve_r() replacement code + * + * Logic that needs to be considered are the following build cases: + * - newlib networking + * - clib2 networking + * - direct bsdsocket.library networking (usually AmiSSL builds) + * Each with the threaded resolver enabled or not. + * + * With the threaded resolver enabled, try to use gethostbyname_r() where + * available, otherwise (re)open bsdsocket.library and fallback to + * gethostbyname(). + */ + +#include <proto/bsdsocket.h> + +static struct SocketIFace *__CurlISocket = NULL; +static uint32 SocketFeatures = 0; + +#define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01 +#define HAVE_BSDSOCKET_GETADDRINFO 0x02 + +CURLcode Curl_amiga_init(void) +{ + struct SocketIFace *ISocket; + struct Library *base = OpenLibrary("bsdsocket.library", 4); + + if(base) { + ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); + if(ISocket) { + ULONG enabled = 0; + + SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE, + SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled, + TAG_DONE); + + if(enabled) { + SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R; + } + + __CurlISocket = ISocket; + + atexit(Curl_amiga_cleanup); + + return CURLE_OK; + } + CloseLibrary(base); + } + + return CURLE_FAILED_INIT; +} + +void Curl_amiga_cleanup(void) +{ + if(__CurlISocket) { + struct Library *base = __CurlISocket->Data.LibBase; + DropInterface((struct Interface *)__CurlISocket); + CloseLibrary(base); + __CurlISocket = NULL; + } +} + +#ifdef CURLRES_AMIGA +/* + * Because we need to handle the different cases in hostip4.c at run-time, + * not at compile-time, based on what was detected in Curl_amiga_init(), + * we replace it completely with our own as to not complicate the baseline + * code. Assumes malloc/calloc/free are thread safe because Curl_he2ai() + * allocates memory also. + */ + +struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, + int port) +{ + struct Curl_addrinfo *ai = NULL; + struct hostent *h; + struct SocketIFace *ISocket = __CurlISocket; + + if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) { + LONG h_errnop = 0; + struct hostent *buf; + + buf = calloc(1, CURL_HOSTENT_SIZE); + if(buf) { + h = gethostbyname_r((STRPTR)hostname, buf, + (char *)buf + sizeof(struct hostent), + CURL_HOSTENT_SIZE - sizeof(struct hostent), + &h_errnop); + if(h) { + ai = Curl_he2ai(h, port); + } + free(buf); + } + } + else { + #ifdef CURLRES_THREADED + /* gethostbyname() is not thread safe, so we need to reopen bsdsocket + * on the thread's context + */ + struct Library *base = OpenLibrary("bsdsocket.library", 4); + if(base) { + ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); + if(ISocket) { + h = gethostbyname((STRPTR)hostname); + if(h) { + ai = Curl_he2ai(h, port); + } + DropInterface((struct Interface *)ISocket); + } + CloseLibrary(base); + } + #else + /* not using threaded resolver - safe to use this as-is */ + h = gethostbyname(hostname); + if(h) { + ai = Curl_he2ai(h, port); + } + #endif + } + + return ai; +} +#endif /* CURLRES_AMIGA */ #ifdef USE_AMISSL int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds, @@ -54,7 +187,11 @@ int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds, } #endif /* USE_AMISSL */ -#elif defined(HAVE_PROTO_BSDSOCKET_H) && !defined(USE_AMISSL) +#elif !defined(USE_AMISSL) /* __amigaos4__ */ +/* + * Amiga OS3 specific code + */ + struct Library *SocketBase = NULL; extern int errno, h_errno; @@ -64,7 +201,7 @@ void __request(const char *msg); # define __request(msg) Printf(msg "\n\a") #endif -void Curl_amiga_cleanup() +void Curl_amiga_cleanup(void) { if(SocketBase) { CloseLibrary(SocketBase); @@ -72,35 +209,36 @@ void Curl_amiga_cleanup() } } -bool Curl_amiga_init() +CURLcode Curl_amiga_init(void) { if(!SocketBase) SocketBase = OpenLibrary("bsdsocket.library", 4); if(!SocketBase) { __request("No TCP/IP Stack running!"); - return FALSE; + return CURLE_FAILED_INIT; } if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno, SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl", TAG_DONE)) { __request("SocketBaseTags ERROR"); - return FALSE; + return CURLE_FAILED_INIT; } #ifndef __libnix__ atexit(Curl_amiga_cleanup); #endif - return TRUE; + return CURLE_OK; } #ifdef __libnix__ ADD2EXIT(Curl_amiga_cleanup, -50); #endif +#endif /* !USE_AMISSL */ + #endif /* HAVE_PROTO_BSDSOCKET_H */ #endif /* __AMIGA__ */ - diff --git a/lib/amigaos.h b/lib/amigaos.h index 5255194dc..9abfb59ea 100644 --- a/lib/amigaos.h +++ b/lib/amigaos.h @@ -25,14 +25,15 @@ ***************************************************************************/ #include "curl_setup.h" -#if defined(__AMIGA__) && defined(HAVE_BSDSOCKET_H) && !defined(USE_AMISSL) +#if defined(__AMIGA__) && defined(HAVE_PROTO_BSDSOCKET_H) && \ + (!defined(USE_AMISSL) || defined(__amigaos4__)) -bool Curl_amiga_init(); -void Curl_amiga_cleanup(); +CURLcode Curl_amiga_init(void); +void Curl_amiga_cleanup(void); #else -#define Curl_amiga_init() 1 +#define Curl_amiga_init() CURLE_OK #define Curl_amiga_cleanup() Curl_nop_stmt #endif diff --git a/lib/curl_setup.h b/lib/curl_setup.h index 85d586180..e5356dcc9 100644 --- a/lib/curl_setup.h +++ b/lib/curl_setup.h @@ -274,6 +274,18 @@ #endif #ifdef __AMIGA__ +# ifdef __amigaos4__ +# define __USE_INLINE__ + /* use our own resolver which uses runtime feature detection */ +# define CURLRES_AMIGA + /* getaddrinfo() currently crashes bsdsocket.library, so disable */ +# undef HAVE_GETADDRINFO +# if !(defined(__NEWLIB__) || \ + (defined(__CLIB2__) && defined(__THREAD_SAFE))) + /* disable threaded resolver with clib2 - requires newlib or clib-ts */ +# undef USE_THREADS_POSIX +# endif +# endif # include <exec/types.h> # include <exec/execbase.h> # include <proto/exec.h> diff --git a/lib/easy.c b/lib/easy.c index 06a94b01b..e17a461e8 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -177,7 +177,7 @@ static CURLcode global_init(long flags, bool memoryfuncs) #endif #ifdef __AMIGA__ - if(!Curl_amiga_init()) { + if(Curl_amiga_init()) { DEBUGF(fprintf(stderr, "Error: Curl_amiga_init failed\n")); goto fail; } diff --git a/lib/hostip4.c b/lib/hostip4.c index 47da6055a..1dd54e879 100644 --- a/lib/hostip4.c +++ b/lib/hostip4.c @@ -112,7 +112,8 @@ struct Curl_addrinfo *Curl_getaddrinfo(struct Curl_easy *data, #endif /* CURLRES_SYNCH */ #endif /* CURLRES_IPV4 */ -#if defined(CURLRES_IPV4) && !defined(CURLRES_ARES) +#if defined(CURLRES_IPV4) && \ + !defined(CURLRES_ARES) && !defined(CURLRES_AMIGA) /* * Curl_ipv4_resolve_r() - ipv4 threadsafe resolver function. @@ -297,4 +298,5 @@ struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, return ai; } -#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) */ +#endif /* defined(CURLRES_IPV4) && !defined(CURLRES_ARES) && + !defined(CURLRES_AMIGA) */ |