/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id: client.c,v 1.68 2005/03/08 22:21:59 bagder Exp $
 ***************************************************************************/

#include "setup.h"
#include <stdlib.h>
#include <string.h>

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#include "curl/curl.h"
#include "curl/client.h"

/* The last #include file should be: */
#include "memdebug.h"


CURLC *curl_global_client;

#define CURL_CLIENT_HANDLE 0x000bab1f

#define GOOD_CLIENT_HANDLE(x) \
    ((x)&&(((struct Curl_client *)x)->type == CURL_CLIENT_HANDLE))

/* This is the struct known as CURLC on the outside */
struct Curl_client {
  /* First a simple identifier to easier detect if a user mixed up
     this client handle with some other kind.  Set this to
     CURL_CLIENT_HANDLE. */
  long type;

  bool use_global_openssl;
    /* 1 = client can use process' global Open SSL state, and expect it
       to be properly set up */
  bool use_global_gnutls;
    /* 1 = client can use process' global GNU TLS state, and expect it
       to be properly set up */
  bool use_global_sock;
    /* 1 = client can use process' global socket services facility 
       and expect it to be properly set up */
  bool use_charset;
    /* 1 = client should use the CHARSET environment variable value as
       the name of the character set for IDNA
    */
};

CURLC *curl_client_init(void)
{
  struct Curl_client *client;

  client = (void *)malloc(sizeof(*client));

  if(client) {
    client->type = CURL_CLIENT_HANDLE;
    client->use_global_openssl = FALSE;
    client->use_global_gnutls = FALSE;
    client->use_global_sock = FALSE;
    client->use_charset = FALSE;

    return (CURLC *) client;
  }
  else
    return NULL;
}

CURLCcode curl_client_cleanup(CURLC *client_handle)
{
  struct Curl_client *client=(struct Curl_client *)client_handle;

  if(GOOD_CLIENT_HANDLE(client)) {
    client->type = 0; /* not good anymore */

    free(client);

    return CURLC_OK;
  }
  else
    return CURLC_BAD_HANDLE;
}

void curl_client_use_global_openssl(CURLC *client_handle)
{
  struct Curl_client *client=(struct Curl_client *)client_handle;

  client->use_global_openssl = TRUE;
}

void curl_client_use_global_gnutls(CURLC *client_handle)
{
  struct Curl_client *client=(struct Curl_client *)client_handle;

  client->use_global_gnutls = TRUE;
}

void curl_client_use_global_sock(CURLC *client_handle)
{
  struct Curl_client *client=(struct Curl_client *)client_handle;

  client->use_global_sock = TRUE;
}

void curl_client_use_charset(CURLC *client_handle)
{
  struct Curl_client *client=(struct Curl_client *)client_handle;

  client->use_charset = TRUE;
}

bool curl_client_global_sock_ok(CURLC *client_handle)
{
  struct Curl_client *client=(struct Curl_client *)client_handle;

  /* On Unix, it's always OK to use the global socket facility, because
     there's nothing the user has to do to make it usable and virtually
     nothing about using it that can affect another part of the program
     that doesn't involve this Curl client.

     But on Windows and Amiga, the user must explicitly do something to
     set up a socket environment for us, so we make him explicitly tell us
     it's ready to use.
  */
#ifdef WIN32
  return client->use_global_sock;
#endif  
#ifdef _AMIGASF
  return client->use_global_sock;
#endif
  return TRUE;
}

bool curl_client_global_openssl_ok(CURLC *client_handle)
{
  struct Curl_client *client=(struct Curl_client *)client_handle;

  return client->use_global_openssl;
}

bool curl_client_global_gnutls_ok(CURLC *client_handle)
{
  struct Curl_client *client=(struct Curl_client *)client_handle;

  return client->use_global_gnutls;
}

bool curl_client_charset_ok(CURLC *client_handle)
{
  struct Curl_client *client=(struct Curl_client *)client_handle;

  return client->use_charset;
}

