amigaos.c (6364B)
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 72 static struct SocketIFace *__CurlISocket = NULL; 73 static uint32 SocketFeatures = 0; 74 75 #define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01 76 #define HAVE_BSDSOCKET_GETADDRINFO 0x02 77 78 CURLcode 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 108 void 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 runtime, 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 127 struct 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> 182 int 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 == SOCKEINTR)) 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 198 struct Library *SocketBase = NULL; 199 200 #ifdef __libnix__ 201 void __request(const char *msg); 202 #else 203 # define __request(msg) Printf((const unsigned char *)(msg "\n\a"), 0) 204 #endif 205 206 void Curl_amiga_cleanup(void) 207 { 208 if(SocketBase) { 209 CloseLibrary(SocketBase); 210 SocketBase = NULL; 211 } 212 } 213 214 CURLcode Curl_amiga_init(void) 215 { 216 if(!SocketBase) 217 SocketBase = OpenLibrary((const unsigned char *)"bsdsocket.library", 4); 218 219 if(!SocketBase) { 220 __request("No TCP/IP Stack running!"); 221 return CURLE_FAILED_INIT; 222 } 223 224 if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno, 225 SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl", 226 TAG_DONE)) { 227 __request("SocketBaseTags ERROR"); 228 return CURLE_FAILED_INIT; 229 } 230 231 #ifndef __libnix__ 232 atexit(Curl_amiga_cleanup); 233 #endif 234 235 return CURLE_OK; 236 } 237 238 #ifdef __libnix__ 239 ADD2EXIT(Curl_amiga_cleanup, -50); 240 #endif 241 242 #endif /* !USE_AMISSL */ 243 244 #endif /* HAVE_PROTO_BSDSOCKET_H */ 245 246 #endif /* __AMIGA__ */