summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/amigaos.c158
-rw-r--r--lib/amigaos.h9
-rw-r--r--lib/curl_setup.h12
-rw-r--r--lib/easy.c2
-rw-r--r--lib/hostip4.c6
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) */