1/*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 9 * 10 * This software is licensed as described in the file COPYING, which 11 * you should have received as part of this distribution. The terms 12 * are also available at https://curl.se/docs/copyright.html. 13 * 14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15 * copies of the Software, and permit persons to whom the Software is 16 * furnished to do so, under the terms of the COPYING file. 17 * 18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19 * KIND, either express or implied. 20 * 21 * SPDX-License-Identifier: curl 22 * 23 ***************************************************************************/ 24 25#include "curl_setup.h" 26 27#ifdef __AMIGA__ 28 29#include <curl/curl.h> 30 31#include "hostip.h" 32#include "amigaos.h" 33 34#ifdef HAVE_PROTO_BSDSOCKET_H 35# if defined(__amigaos4__) 36# include <bsdsocket/socketbasetags.h> 37# elif !defined(USE_AMISSL) 38# include <amitcp/socketbasetags.h> 39# endif 40# ifdef __libnix__ 41# include <stabs.h> 42# endif 43#endif 44 45/* The last #include files should be: */ 46#include "curl_memory.h" 47#include "memdebug.h" 48 49#ifdef HAVE_PROTO_BSDSOCKET_H 50 51#ifdef __amigaos4__ 52/* 53 * AmigaOS 4.x specific code 54 */ 55 56/* 57 * hostip4.c - Curl_ipv4_resolve_r() replacement code 58 * 59 * Logic that needs to be considered are the following build cases: 60 * - newlib networking 61 * - clib2 networking 62 * - direct bsdsocket.library networking (usually AmiSSL builds) 63 * Each with the threaded resolver enabled or not. 64 * 65 * With the threaded resolver enabled, try to use gethostbyname_r() where 66 * available, otherwise (re)open bsdsocket.library and fallback to 67 * gethostbyname(). 68 */ 69 70#include <proto/bsdsocket.h> 71 72static struct SocketIFace *__CurlISocket = NULL; 73static uint32 SocketFeatures = 0; 74 75#define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01 76#define HAVE_BSDSOCKET_GETADDRINFO 0x02 77 78CURLcode Curl_amiga_init(void) 79{ 80 struct SocketIFace *ISocket; 81 struct Library *base = OpenLibrary("bsdsocket.library", 4); 82 83 if(base) { 84 ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); 85 if(ISocket) { 86 ULONG enabled = 0; 87 88 SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE, 89 SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled, 90 TAG_DONE); 91 92 if(enabled) { 93 SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R; 94 } 95 96 __CurlISocket = ISocket; 97 98 atexit(Curl_amiga_cleanup); 99 100 return CURLE_OK; 101 } 102 CloseLibrary(base); 103 } 104 105 return CURLE_FAILED_INIT; 106} 107 108void Curl_amiga_cleanup(void) 109{ 110 if(__CurlISocket) { 111 struct Library *base = __CurlISocket->Data.LibBase; 112 DropInterface((struct Interface *)__CurlISocket); 113 CloseLibrary(base); 114 __CurlISocket = NULL; 115 } 116} 117 118#ifdef CURLRES_AMIGA 119/* 120 * Because we need to handle the different cases in hostip4.c at run-time, 121 * not at compile-time, based on what was detected in Curl_amiga_init(), 122 * we replace it completely with our own as to not complicate the baseline 123 * code. Assumes malloc/calloc/free are thread safe because Curl_he2ai() 124 * allocates memory also. 125 */ 126 127struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, 128 int port) 129{ 130 struct Curl_addrinfo *ai = NULL; 131 struct hostent *h; 132 struct SocketIFace *ISocket = __CurlISocket; 133 134 if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) { 135 LONG h_errnop = 0; 136 struct hostent *buf; 137 138 buf = calloc(1, CURL_HOSTENT_SIZE); 139 if(buf) { 140 h = gethostbyname_r((STRPTR)hostname, buf, 141 (char *)buf + sizeof(struct hostent), 142 CURL_HOSTENT_SIZE - sizeof(struct hostent), 143 &h_errnop); 144 if(h) { 145 ai = Curl_he2ai(h, port); 146 } 147 free(buf); 148 } 149 } 150 else { 151 #ifdef CURLRES_THREADED 152 /* gethostbyname() is not thread safe, so we need to reopen bsdsocket 153 * on the thread's context 154 */ 155 struct Library *base = OpenLibrary("bsdsocket.library", 4); 156 if(base) { 157 ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL); 158 if(ISocket) { 159 h = gethostbyname((STRPTR)hostname); 160 if(h) { 161 ai = Curl_he2ai(h, port); 162 } 163 DropInterface((struct Interface *)ISocket); 164 } 165 CloseLibrary(base); 166 } 167 #else 168 /* not using threaded resolver - safe to use this as-is */ 169 h = gethostbyname(hostname); 170 if(h) { 171 ai = Curl_he2ai(h, port); 172 } 173 #endif 174 } 175 176 return ai; 177} 178#endif /* CURLRES_AMIGA */ 179 180#ifdef USE_AMISSL 181#include <signal.h> 182int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds, 183 fd_set *errorfds, struct timeval *timeout) 184{ 185 int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0); 186 /* Ensure Ctrl-C signal is actioned */ 187 if((r == -1) && (SOCKERRNO == EINTR)) 188 raise(SIGINT); 189 return r; 190} 191#endif /* USE_AMISSL */ 192 193#elif !defined(USE_AMISSL) /* __amigaos4__ */ 194/* 195 * Amiga OS3 specific code 196 */ 197 198struct Library *SocketBase = NULL; 199extern int errno, h_errno; 200 201#ifdef __libnix__ 202void __request(const char *msg); 203#else 204# define __request(msg) Printf(msg "\n\a") 205#endif 206 207void Curl_amiga_cleanup(void) 208{ 209 if(SocketBase) { 210 CloseLibrary(SocketBase); 211 SocketBase = NULL; 212 } 213} 214 215CURLcode Curl_amiga_init(void) 216{ 217 if(!SocketBase) 218 SocketBase = OpenLibrary("bsdsocket.library", 4); 219 220 if(!SocketBase) { 221 __request("No TCP/IP Stack running!"); 222 return CURLE_FAILED_INIT; 223 } 224 225 if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno, 226 SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl", 227 TAG_DONE)) { 228 __request("SocketBaseTags ERROR"); 229 return CURLE_FAILED_INIT; 230 } 231 232#ifndef __libnix__ 233 atexit(Curl_amiga_cleanup); 234#endif 235 236 return CURLE_OK; 237} 238 239#ifdef __libnix__ 240ADD2EXIT(Curl_amiga_cleanup, -50); 241#endif 242 243#endif /* !USE_AMISSL */ 244 245#endif /* HAVE_PROTO_BSDSOCKET_H */ 246 247#endif /* __AMIGA__ */ 248