amigaos.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  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. #include "curl_setup.h"
  25. #ifdef __AMIGA__
  26. #include <curl/curl.h>
  27. #include "hostip.h"
  28. #include "amigaos.h"
  29. #ifdef HAVE_PROTO_BSDSOCKET_H
  30. # if defined(__amigaos4__)
  31. # include <bsdsocket/socketbasetags.h>
  32. # elif !defined(USE_AMISSL)
  33. # include <amitcp/socketbasetags.h>
  34. # endif
  35. # ifdef __libnix__
  36. # include <stabs.h>
  37. # endif
  38. #endif
  39. /* The last #include files should be: */
  40. #include "curl_memory.h"
  41. #include "memdebug.h"
  42. #ifdef HAVE_PROTO_BSDSOCKET_H
  43. #ifdef __amigaos4__
  44. /*
  45. * AmigaOS 4.x specific code
  46. */
  47. /*
  48. * hostip4.c - Curl_ipv4_resolve_r() replacement code
  49. *
  50. * Logic that needs to be considered are the following build cases:
  51. * - newlib networking
  52. * - clib2 networking
  53. * - direct bsdsocket.library networking (usually AmiSSL builds)
  54. * Each with the threaded resolver enabled or not.
  55. *
  56. * With the threaded resolver enabled, try to use gethostbyname_r() where
  57. * available, otherwise (re)open bsdsocket.library and fallback to
  58. * gethostbyname().
  59. */
  60. #include <proto/bsdsocket.h>
  61. static struct SocketIFace *__CurlISocket = NULL;
  62. static uint32 SocketFeatures = 0;
  63. #define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01
  64. #define HAVE_BSDSOCKET_GETADDRINFO 0x02
  65. CURLcode Curl_amiga_init(void)
  66. {
  67. struct SocketIFace *ISocket;
  68. struct Library *base = OpenLibrary("bsdsocket.library", 4);
  69. if(base) {
  70. ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
  71. if(ISocket) {
  72. ULONG enabled = 0;
  73. SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE,
  74. SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled,
  75. TAG_DONE);
  76. if(enabled) {
  77. SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R;
  78. }
  79. __CurlISocket = ISocket;
  80. atexit(Curl_amiga_cleanup);
  81. return CURLE_OK;
  82. }
  83. CloseLibrary(base);
  84. }
  85. return CURLE_FAILED_INIT;
  86. }
  87. void Curl_amiga_cleanup(void)
  88. {
  89. if(__CurlISocket) {
  90. struct Library *base = __CurlISocket->Data.LibBase;
  91. DropInterface((struct Interface *)__CurlISocket);
  92. CloseLibrary(base);
  93. __CurlISocket = NULL;
  94. }
  95. }
  96. #ifdef CURLRES_AMIGA
  97. /*
  98. * Because we need to handle the different cases in hostip4.c at run-time,
  99. * not at compile-time, based on what was detected in Curl_amiga_init(),
  100. * we replace it completely with our own as to not complicate the baseline
  101. * code. Assumes malloc/calloc/free are thread safe because Curl_he2ai()
  102. * allocates memory also.
  103. */
  104. struct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
  105. int port)
  106. {
  107. struct Curl_addrinfo *ai = NULL;
  108. struct hostent *h;
  109. struct SocketIFace *ISocket = __CurlISocket;
  110. if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) {
  111. LONG h_errnop = 0;
  112. struct hostent *buf;
  113. buf = calloc(1, CURL_HOSTENT_SIZE);
  114. if(buf) {
  115. h = gethostbyname_r((STRPTR)hostname, buf,
  116. (char *)buf + sizeof(struct hostent),
  117. CURL_HOSTENT_SIZE - sizeof(struct hostent),
  118. &h_errnop);
  119. if(h) {
  120. ai = Curl_he2ai(h, port);
  121. }
  122. free(buf);
  123. }
  124. }
  125. else {
  126. #ifdef CURLRES_THREADED
  127. /* gethostbyname() is not thread safe, so we need to reopen bsdsocket
  128. * on the thread's context
  129. */
  130. struct Library *base = OpenLibrary("bsdsocket.library", 4);
  131. if(base) {
  132. ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
  133. if(ISocket) {
  134. h = gethostbyname((STRPTR)hostname);
  135. if(h) {
  136. ai = Curl_he2ai(h, port);
  137. }
  138. DropInterface((struct Interface *)ISocket);
  139. }
  140. CloseLibrary(base);
  141. }
  142. #else
  143. /* not using threaded resolver - safe to use this as-is */
  144. h = gethostbyname(hostname);
  145. if(h) {
  146. ai = Curl_he2ai(h, port);
  147. }
  148. #endif
  149. }
  150. return ai;
  151. }
  152. #endif /* CURLRES_AMIGA */
  153. #ifdef USE_AMISSL
  154. #include <signal.h>
  155. int Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
  156. fd_set *errorfds, struct timeval *timeout)
  157. {
  158. int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0);
  159. /* Ensure Ctrl-C signal is actioned */
  160. if((r == -1) && (SOCKERRNO == EINTR))
  161. raise(SIGINT);
  162. return r;
  163. }
  164. #endif /* USE_AMISSL */
  165. #elif !defined(USE_AMISSL) /* __amigaos4__ */
  166. /*
  167. * Amiga OS3 specific code
  168. */
  169. struct Library *SocketBase = NULL;
  170. extern int errno, h_errno;
  171. #ifdef __libnix__
  172. void __request(const char *msg);
  173. #else
  174. # define __request(msg) Printf(msg "\n\a")
  175. #endif
  176. void Curl_amiga_cleanup(void)
  177. {
  178. if(SocketBase) {
  179. CloseLibrary(SocketBase);
  180. SocketBase = NULL;
  181. }
  182. }
  183. CURLcode Curl_amiga_init(void)
  184. {
  185. if(!SocketBase)
  186. SocketBase = OpenLibrary("bsdsocket.library", 4);
  187. if(!SocketBase) {
  188. __request("No TCP/IP Stack running!");
  189. return CURLE_FAILED_INIT;
  190. }
  191. if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
  192. SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
  193. TAG_DONE)) {
  194. __request("SocketBaseTags ERROR");
  195. return CURLE_FAILED_INIT;
  196. }
  197. #ifndef __libnix__
  198. atexit(Curl_amiga_cleanup);
  199. #endif
  200. return CURLE_OK;
  201. }
  202. #ifdef __libnix__
  203. ADD2EXIT(Curl_amiga_cleanup, -50);
  204. #endif
  205. #endif /* !USE_AMISSL */
  206. #endif /* HAVE_PROTO_BSDSOCKET_H */
  207. #endif /* __AMIGA__ */