113498266Sopenharmony_ci/***************************************************************************
213498266Sopenharmony_ci *                                  _   _ ____  _
313498266Sopenharmony_ci *  Project                     ___| | | |  _ \| |
413498266Sopenharmony_ci *                             / __| | | | |_) | |
513498266Sopenharmony_ci *                            | (__| |_| |  _ <| |___
613498266Sopenharmony_ci *                             \___|\___/|_| \_\_____|
713498266Sopenharmony_ci *
813498266Sopenharmony_ci * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
913498266Sopenharmony_ci *
1013498266Sopenharmony_ci * This software is licensed as described in the file COPYING, which
1113498266Sopenharmony_ci * you should have received as part of this distribution. The terms
1213498266Sopenharmony_ci * are also available at https://curl.se/docs/copyright.html.
1313498266Sopenharmony_ci *
1413498266Sopenharmony_ci * You may opt to use, copy, modify, merge, publish, distribute and/or sell
1513498266Sopenharmony_ci * copies of the Software, and permit persons to whom the Software is
1613498266Sopenharmony_ci * furnished to do so, under the terms of the COPYING file.
1713498266Sopenharmony_ci *
1813498266Sopenharmony_ci * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
1913498266Sopenharmony_ci * KIND, either express or implied.
2013498266Sopenharmony_ci *
2113498266Sopenharmony_ci * SPDX-License-Identifier: curl
2213498266Sopenharmony_ci *
2313498266Sopenharmony_ci ***************************************************************************/
2413498266Sopenharmony_ci
2513498266Sopenharmony_ci#include "curl_setup.h"
2613498266Sopenharmony_ci
2713498266Sopenharmony_ci#ifdef __AMIGA__
2813498266Sopenharmony_ci
2913498266Sopenharmony_ci#include <curl/curl.h>
3013498266Sopenharmony_ci
3113498266Sopenharmony_ci#include "hostip.h"
3213498266Sopenharmony_ci#include "amigaos.h"
3313498266Sopenharmony_ci
3413498266Sopenharmony_ci#ifdef HAVE_PROTO_BSDSOCKET_H
3513498266Sopenharmony_ci#  if defined(__amigaos4__)
3613498266Sopenharmony_ci#    include <bsdsocket/socketbasetags.h>
3713498266Sopenharmony_ci#  elif !defined(USE_AMISSL)
3813498266Sopenharmony_ci#    include <amitcp/socketbasetags.h>
3913498266Sopenharmony_ci#  endif
4013498266Sopenharmony_ci#  ifdef __libnix__
4113498266Sopenharmony_ci#    include <stabs.h>
4213498266Sopenharmony_ci#  endif
4313498266Sopenharmony_ci#endif
4413498266Sopenharmony_ci
4513498266Sopenharmony_ci/* The last #include files should be: */
4613498266Sopenharmony_ci#include "curl_memory.h"
4713498266Sopenharmony_ci#include "memdebug.h"
4813498266Sopenharmony_ci
4913498266Sopenharmony_ci#ifdef HAVE_PROTO_BSDSOCKET_H
5013498266Sopenharmony_ci
5113498266Sopenharmony_ci#ifdef __amigaos4__
5213498266Sopenharmony_ci/*
5313498266Sopenharmony_ci * AmigaOS 4.x specific code
5413498266Sopenharmony_ci */
5513498266Sopenharmony_ci
5613498266Sopenharmony_ci/*
5713498266Sopenharmony_ci * hostip4.c - Curl_ipv4_resolve_r() replacement code
5813498266Sopenharmony_ci *
5913498266Sopenharmony_ci * Logic that needs to be considered are the following build cases:
6013498266Sopenharmony_ci * - newlib networking
6113498266Sopenharmony_ci * - clib2 networking
6213498266Sopenharmony_ci * - direct bsdsocket.library networking (usually AmiSSL builds)
6313498266Sopenharmony_ci * Each with the threaded resolver enabled or not.
6413498266Sopenharmony_ci *
6513498266Sopenharmony_ci * With the threaded resolver enabled, try to use gethostbyname_r() where
6613498266Sopenharmony_ci * available, otherwise (re)open bsdsocket.library and fallback to
6713498266Sopenharmony_ci * gethostbyname().
6813498266Sopenharmony_ci */
6913498266Sopenharmony_ci
7013498266Sopenharmony_ci#include <proto/bsdsocket.h>
7113498266Sopenharmony_ci
7213498266Sopenharmony_cistatic struct SocketIFace *__CurlISocket = NULL;
7313498266Sopenharmony_cistatic uint32 SocketFeatures = 0;
7413498266Sopenharmony_ci
7513498266Sopenharmony_ci#define HAVE_BSDSOCKET_GETHOSTBYNAME_R 0x01
7613498266Sopenharmony_ci#define HAVE_BSDSOCKET_GETADDRINFO     0x02
7713498266Sopenharmony_ci
7813498266Sopenharmony_ciCURLcode Curl_amiga_init(void)
7913498266Sopenharmony_ci{
8013498266Sopenharmony_ci  struct SocketIFace *ISocket;
8113498266Sopenharmony_ci  struct Library *base = OpenLibrary("bsdsocket.library", 4);
8213498266Sopenharmony_ci
8313498266Sopenharmony_ci  if(base) {
8413498266Sopenharmony_ci    ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
8513498266Sopenharmony_ci    if(ISocket) {
8613498266Sopenharmony_ci      ULONG enabled = 0;
8713498266Sopenharmony_ci
8813498266Sopenharmony_ci      SocketBaseTags(SBTM_SETVAL(SBTC_CAN_SHARE_LIBRARY_BASES), TRUE,
8913498266Sopenharmony_ci                     SBTM_GETREF(SBTC_HAVE_GETHOSTADDR_R_API), (ULONG)&enabled,
9013498266Sopenharmony_ci                     TAG_DONE);
9113498266Sopenharmony_ci
9213498266Sopenharmony_ci      if(enabled) {
9313498266Sopenharmony_ci        SocketFeatures |= HAVE_BSDSOCKET_GETHOSTBYNAME_R;
9413498266Sopenharmony_ci      }
9513498266Sopenharmony_ci
9613498266Sopenharmony_ci      __CurlISocket = ISocket;
9713498266Sopenharmony_ci
9813498266Sopenharmony_ci      atexit(Curl_amiga_cleanup);
9913498266Sopenharmony_ci
10013498266Sopenharmony_ci      return CURLE_OK;
10113498266Sopenharmony_ci    }
10213498266Sopenharmony_ci    CloseLibrary(base);
10313498266Sopenharmony_ci  }
10413498266Sopenharmony_ci
10513498266Sopenharmony_ci  return CURLE_FAILED_INIT;
10613498266Sopenharmony_ci}
10713498266Sopenharmony_ci
10813498266Sopenharmony_civoid Curl_amiga_cleanup(void)
10913498266Sopenharmony_ci{
11013498266Sopenharmony_ci  if(__CurlISocket) {
11113498266Sopenharmony_ci    struct Library *base = __CurlISocket->Data.LibBase;
11213498266Sopenharmony_ci    DropInterface((struct Interface *)__CurlISocket);
11313498266Sopenharmony_ci    CloseLibrary(base);
11413498266Sopenharmony_ci    __CurlISocket = NULL;
11513498266Sopenharmony_ci  }
11613498266Sopenharmony_ci}
11713498266Sopenharmony_ci
11813498266Sopenharmony_ci#ifdef CURLRES_AMIGA
11913498266Sopenharmony_ci/*
12013498266Sopenharmony_ci * Because we need to handle the different cases in hostip4.c at run-time,
12113498266Sopenharmony_ci * not at compile-time, based on what was detected in Curl_amiga_init(),
12213498266Sopenharmony_ci * we replace it completely with our own as to not complicate the baseline
12313498266Sopenharmony_ci * code. Assumes malloc/calloc/free are thread safe because Curl_he2ai()
12413498266Sopenharmony_ci * allocates memory also.
12513498266Sopenharmony_ci */
12613498266Sopenharmony_ci
12713498266Sopenharmony_cistruct Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
12813498266Sopenharmony_ci                                          int port)
12913498266Sopenharmony_ci{
13013498266Sopenharmony_ci  struct Curl_addrinfo *ai = NULL;
13113498266Sopenharmony_ci  struct hostent *h;
13213498266Sopenharmony_ci  struct SocketIFace *ISocket = __CurlISocket;
13313498266Sopenharmony_ci
13413498266Sopenharmony_ci  if(SocketFeatures & HAVE_BSDSOCKET_GETHOSTBYNAME_R) {
13513498266Sopenharmony_ci    LONG h_errnop = 0;
13613498266Sopenharmony_ci    struct hostent *buf;
13713498266Sopenharmony_ci
13813498266Sopenharmony_ci    buf = calloc(1, CURL_HOSTENT_SIZE);
13913498266Sopenharmony_ci    if(buf) {
14013498266Sopenharmony_ci      h = gethostbyname_r((STRPTR)hostname, buf,
14113498266Sopenharmony_ci                          (char *)buf + sizeof(struct hostent),
14213498266Sopenharmony_ci                          CURL_HOSTENT_SIZE - sizeof(struct hostent),
14313498266Sopenharmony_ci                          &h_errnop);
14413498266Sopenharmony_ci      if(h) {
14513498266Sopenharmony_ci        ai = Curl_he2ai(h, port);
14613498266Sopenharmony_ci      }
14713498266Sopenharmony_ci      free(buf);
14813498266Sopenharmony_ci    }
14913498266Sopenharmony_ci  }
15013498266Sopenharmony_ci  else {
15113498266Sopenharmony_ci    #ifdef CURLRES_THREADED
15213498266Sopenharmony_ci    /* gethostbyname() is not thread safe, so we need to reopen bsdsocket
15313498266Sopenharmony_ci     * on the thread's context
15413498266Sopenharmony_ci     */
15513498266Sopenharmony_ci    struct Library *base = OpenLibrary("bsdsocket.library", 4);
15613498266Sopenharmony_ci    if(base) {
15713498266Sopenharmony_ci      ISocket = (struct SocketIFace *)GetInterface(base, "main", 1, NULL);
15813498266Sopenharmony_ci      if(ISocket) {
15913498266Sopenharmony_ci        h = gethostbyname((STRPTR)hostname);
16013498266Sopenharmony_ci        if(h) {
16113498266Sopenharmony_ci          ai = Curl_he2ai(h, port);
16213498266Sopenharmony_ci        }
16313498266Sopenharmony_ci        DropInterface((struct Interface *)ISocket);
16413498266Sopenharmony_ci      }
16513498266Sopenharmony_ci      CloseLibrary(base);
16613498266Sopenharmony_ci    }
16713498266Sopenharmony_ci    #else
16813498266Sopenharmony_ci    /* not using threaded resolver - safe to use this as-is */
16913498266Sopenharmony_ci    h = gethostbyname(hostname);
17013498266Sopenharmony_ci    if(h) {
17113498266Sopenharmony_ci      ai = Curl_he2ai(h, port);
17213498266Sopenharmony_ci    }
17313498266Sopenharmony_ci    #endif
17413498266Sopenharmony_ci  }
17513498266Sopenharmony_ci
17613498266Sopenharmony_ci  return ai;
17713498266Sopenharmony_ci}
17813498266Sopenharmony_ci#endif /* CURLRES_AMIGA */
17913498266Sopenharmony_ci
18013498266Sopenharmony_ci#ifdef USE_AMISSL
18113498266Sopenharmony_ci#include <signal.h>
18213498266Sopenharmony_ciint Curl_amiga_select(int nfds, fd_set *readfds, fd_set *writefds,
18313498266Sopenharmony_ci                      fd_set *errorfds, struct timeval *timeout)
18413498266Sopenharmony_ci{
18513498266Sopenharmony_ci  int r = WaitSelect(nfds, readfds, writefds, errorfds, timeout, 0);
18613498266Sopenharmony_ci  /* Ensure Ctrl-C signal is actioned */
18713498266Sopenharmony_ci  if((r == -1) && (SOCKERRNO == EINTR))
18813498266Sopenharmony_ci    raise(SIGINT);
18913498266Sopenharmony_ci  return r;
19013498266Sopenharmony_ci}
19113498266Sopenharmony_ci#endif /* USE_AMISSL */
19213498266Sopenharmony_ci
19313498266Sopenharmony_ci#elif !defined(USE_AMISSL) /* __amigaos4__ */
19413498266Sopenharmony_ci/*
19513498266Sopenharmony_ci * Amiga OS3 specific code
19613498266Sopenharmony_ci */
19713498266Sopenharmony_ci
19813498266Sopenharmony_cistruct Library *SocketBase = NULL;
19913498266Sopenharmony_ciextern int errno, h_errno;
20013498266Sopenharmony_ci
20113498266Sopenharmony_ci#ifdef __libnix__
20213498266Sopenharmony_civoid __request(const char *msg);
20313498266Sopenharmony_ci#else
20413498266Sopenharmony_ci# define __request(msg)       Printf(msg "\n\a")
20513498266Sopenharmony_ci#endif
20613498266Sopenharmony_ci
20713498266Sopenharmony_civoid Curl_amiga_cleanup(void)
20813498266Sopenharmony_ci{
20913498266Sopenharmony_ci  if(SocketBase) {
21013498266Sopenharmony_ci    CloseLibrary(SocketBase);
21113498266Sopenharmony_ci    SocketBase = NULL;
21213498266Sopenharmony_ci  }
21313498266Sopenharmony_ci}
21413498266Sopenharmony_ci
21513498266Sopenharmony_ciCURLcode Curl_amiga_init(void)
21613498266Sopenharmony_ci{
21713498266Sopenharmony_ci  if(!SocketBase)
21813498266Sopenharmony_ci    SocketBase = OpenLibrary("bsdsocket.library", 4);
21913498266Sopenharmony_ci
22013498266Sopenharmony_ci  if(!SocketBase) {
22113498266Sopenharmony_ci    __request("No TCP/IP Stack running!");
22213498266Sopenharmony_ci    return CURLE_FAILED_INIT;
22313498266Sopenharmony_ci  }
22413498266Sopenharmony_ci
22513498266Sopenharmony_ci  if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
22613498266Sopenharmony_ci                    SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
22713498266Sopenharmony_ci                    TAG_DONE)) {
22813498266Sopenharmony_ci    __request("SocketBaseTags ERROR");
22913498266Sopenharmony_ci    return CURLE_FAILED_INIT;
23013498266Sopenharmony_ci  }
23113498266Sopenharmony_ci
23213498266Sopenharmony_ci#ifndef __libnix__
23313498266Sopenharmony_ci  atexit(Curl_amiga_cleanup);
23413498266Sopenharmony_ci#endif
23513498266Sopenharmony_ci
23613498266Sopenharmony_ci  return CURLE_OK;
23713498266Sopenharmony_ci}
23813498266Sopenharmony_ci
23913498266Sopenharmony_ci#ifdef __libnix__
24013498266Sopenharmony_ciADD2EXIT(Curl_amiga_cleanup, -50);
24113498266Sopenharmony_ci#endif
24213498266Sopenharmony_ci
24313498266Sopenharmony_ci#endif /* !USE_AMISSL */
24413498266Sopenharmony_ci
24513498266Sopenharmony_ci#endif /* HAVE_PROTO_BSDSOCKET_H */
24613498266Sopenharmony_ci
24713498266Sopenharmony_ci#endif /* __AMIGA__ */
248