+static void gnutls_log_function (int, const char *);
+static void gnutls_log_function2 (int, const char*, const char*);
+
+\f
+#ifdef WINDOWSNT
+
+/* Macro for defining functions that will be loaded from the GnuTLS DLL. */
+#define DEF_GNUTLS_FN(rettype,func,args) static rettype (FAR CDECL *fn_##func)args
+
+/* Macro for loading GnuTLS functions from the library. */
+#define LOAD_GNUTLS_FN(lib,func) { \
+ fn_##func = (void *) GetProcAddress (lib, #func); \
+ if (!fn_##func) return 0; \
+ }
+
+DEF_GNUTLS_FN (gnutls_alert_description_t, gnutls_alert_get,
+ (gnutls_session_t));
+DEF_GNUTLS_FN (const char *, gnutls_alert_get_name,
+ (gnutls_alert_description_t));
+DEF_GNUTLS_FN (int, gnutls_alert_send_appropriate, (gnutls_session_t, int));
+DEF_GNUTLS_FN (int, gnutls_anon_allocate_client_credentials,
+ (gnutls_anon_client_credentials_t *));
+DEF_GNUTLS_FN (void, gnutls_anon_free_client_credentials,
+ (gnutls_anon_client_credentials_t));
+DEF_GNUTLS_FN (int, gnutls_bye, (gnutls_session_t, gnutls_close_request_t));
+DEF_GNUTLS_FN (int, gnutls_certificate_allocate_credentials,
+ (gnutls_certificate_credentials_t *));
+DEF_GNUTLS_FN (void, gnutls_certificate_free_credentials,
+ (gnutls_certificate_credentials_t));
+DEF_GNUTLS_FN (const gnutls_datum_t *, gnutls_certificate_get_peers,
+ (gnutls_session_t, unsigned int *));
+DEF_GNUTLS_FN (void, gnutls_certificate_set_verify_flags,
+ (gnutls_certificate_credentials_t, unsigned int));
+DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_crl_file,
+ (gnutls_certificate_credentials_t, const char *,
+ gnutls_x509_crt_fmt_t));
+DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_key_file,
+ (gnutls_certificate_credentials_t, const char *, const char *,
+ gnutls_x509_crt_fmt_t));
+DEF_GNUTLS_FN (int, gnutls_certificate_set_x509_trust_file,
+ (gnutls_certificate_credentials_t, const char *,
+ gnutls_x509_crt_fmt_t));
+DEF_GNUTLS_FN (gnutls_certificate_type_t, gnutls_certificate_type_get,
+ (gnutls_session_t));
+DEF_GNUTLS_FN (int, gnutls_certificate_verify_peers2,
+ (gnutls_session_t, unsigned int *));
+DEF_GNUTLS_FN (int, gnutls_credentials_set,
+ (gnutls_session_t, gnutls_credentials_type_t, void *));
+DEF_GNUTLS_FN (void, gnutls_deinit, (gnutls_session_t));
+DEF_GNUTLS_FN (void, gnutls_dh_set_prime_bits,
+ (gnutls_session_t, unsigned int));
+DEF_GNUTLS_FN (int, gnutls_error_is_fatal, (int));
+DEF_GNUTLS_FN (int, gnutls_global_init, (void));
+DEF_GNUTLS_FN (void, gnutls_global_set_log_function, (gnutls_log_func));
+DEF_GNUTLS_FN (void, gnutls_global_set_log_level, (int));
+DEF_GNUTLS_FN (void, gnutls_global_set_mem_functions,
+ (gnutls_alloc_function, gnutls_alloc_function,
+ gnutls_is_secure_function, gnutls_realloc_function,
+ gnutls_free_function));
+DEF_GNUTLS_FN (int, gnutls_handshake, (gnutls_session_t));
+DEF_GNUTLS_FN (int, gnutls_init, (gnutls_session_t *, gnutls_connection_end_t));
+DEF_GNUTLS_FN (int, gnutls_priority_set_direct,
+ (gnutls_session_t, const char *, const char **));
+DEF_GNUTLS_FN (size_t, gnutls_record_check_pending, (gnutls_session_t));
+DEF_GNUTLS_FN (ssize_t, gnutls_record_recv, (gnutls_session_t, void *, size_t));
+DEF_GNUTLS_FN (ssize_t, gnutls_record_send,
+ (gnutls_session_t, const void *, size_t));
+DEF_GNUTLS_FN (const char *, gnutls_strerror, (int));
+DEF_GNUTLS_FN (void, gnutls_transport_set_errno, (gnutls_session_t, int));
+DEF_GNUTLS_FN (const char *, gnutls_check_version, (const char *));
+DEF_GNUTLS_FN (void, gnutls_transport_set_lowat, (gnutls_session_t, int));
+DEF_GNUTLS_FN (void, gnutls_transport_set_ptr2,
+ (gnutls_session_t, gnutls_transport_ptr_t,
+ gnutls_transport_ptr_t));
+DEF_GNUTLS_FN (void, gnutls_transport_set_pull_function,
+ (gnutls_session_t, gnutls_pull_func));
+DEF_GNUTLS_FN (void, gnutls_transport_set_push_function,
+ (gnutls_session_t, gnutls_push_func));
+DEF_GNUTLS_FN (int, gnutls_x509_crt_check_hostname,
+ (gnutls_x509_crt_t, const char *));
+DEF_GNUTLS_FN (void, gnutls_x509_crt_deinit, (gnutls_x509_crt_t));
+DEF_GNUTLS_FN (int, gnutls_x509_crt_import,
+ (gnutls_x509_crt_t, const gnutls_datum_t *,
+ gnutls_x509_crt_fmt_t));
+DEF_GNUTLS_FN (int, gnutls_x509_crt_init, (gnutls_x509_crt_t *));
+
+static int
+init_gnutls_functions (Lisp_Object libraries)
+{
+ HMODULE library;
+ int max_log_level = 1;
+
+ if (!(library = w32_delayed_load (libraries, Qgnutls_dll)))
+ {
+ GNUTLS_LOG (1, max_log_level, "GnuTLS library not found");
+ return 0;
+ }
+
+ LOAD_GNUTLS_FN (library, gnutls_alert_get);
+ LOAD_GNUTLS_FN (library, gnutls_alert_get_name);
+ LOAD_GNUTLS_FN (library, gnutls_alert_send_appropriate);
+ LOAD_GNUTLS_FN (library, gnutls_anon_allocate_client_credentials);
+ LOAD_GNUTLS_FN (library, gnutls_anon_free_client_credentials);
+ LOAD_GNUTLS_FN (library, gnutls_bye);
+ LOAD_GNUTLS_FN (library, gnutls_certificate_allocate_credentials);
+ LOAD_GNUTLS_FN (library, gnutls_certificate_free_credentials);
+ LOAD_GNUTLS_FN (library, gnutls_certificate_get_peers);
+ LOAD_GNUTLS_FN (library, gnutls_certificate_set_verify_flags);
+ LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_crl_file);
+ LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_key_file);
+ LOAD_GNUTLS_FN (library, gnutls_certificate_set_x509_trust_file);
+ LOAD_GNUTLS_FN (library, gnutls_certificate_type_get);
+ LOAD_GNUTLS_FN (library, gnutls_certificate_verify_peers2);
+ LOAD_GNUTLS_FN (library, gnutls_credentials_set);
+ LOAD_GNUTLS_FN (library, gnutls_deinit);
+ LOAD_GNUTLS_FN (library, gnutls_dh_set_prime_bits);
+ LOAD_GNUTLS_FN (library, gnutls_error_is_fatal);
+ LOAD_GNUTLS_FN (library, gnutls_global_init);
+ LOAD_GNUTLS_FN (library, gnutls_global_set_log_function);
+ LOAD_GNUTLS_FN (library, gnutls_global_set_log_level);
+ LOAD_GNUTLS_FN (library, gnutls_global_set_mem_functions);
+ LOAD_GNUTLS_FN (library, gnutls_handshake);
+ LOAD_GNUTLS_FN (library, gnutls_init);
+ LOAD_GNUTLS_FN (library, gnutls_priority_set_direct);
+ LOAD_GNUTLS_FN (library, gnutls_record_check_pending);
+ LOAD_GNUTLS_FN (library, gnutls_record_recv);
+ LOAD_GNUTLS_FN (library, gnutls_record_send);
+ LOAD_GNUTLS_FN (library, gnutls_strerror);
+ LOAD_GNUTLS_FN (library, gnutls_transport_set_errno);
+ LOAD_GNUTLS_FN (library, gnutls_check_version);
+ /* We don't need to call gnutls_transport_set_lowat in GnuTLS 2.11.1
+ and later, and the function was removed entirely in 3.0.0. */
+ if (!fn_gnutls_check_version ("2.11.1"))
+ LOAD_GNUTLS_FN (library, gnutls_transport_set_lowat);
+ LOAD_GNUTLS_FN (library, gnutls_transport_set_ptr2);
+ LOAD_GNUTLS_FN (library, gnutls_transport_set_pull_function);
+ LOAD_GNUTLS_FN (library, gnutls_transport_set_push_function);
+ LOAD_GNUTLS_FN (library, gnutls_x509_crt_check_hostname);
+ LOAD_GNUTLS_FN (library, gnutls_x509_crt_deinit);
+ LOAD_GNUTLS_FN (library, gnutls_x509_crt_import);
+ LOAD_GNUTLS_FN (library, gnutls_x509_crt_init);
+
+ max_log_level = global_gnutls_log_level;
+
+ GNUTLS_LOG2 (1, max_log_level, "GnuTLS library loaded:",
+ SDATA (Fget (Qgnutls_dll, QCloaded_from)));
+ return 1;
+}
+
+#else /* !WINDOWSNT */
+
+#define fn_gnutls_alert_get gnutls_alert_get
+#define fn_gnutls_alert_get_name gnutls_alert_get_name
+#define fn_gnutls_alert_send_appropriate gnutls_alert_send_appropriate
+#define fn_gnutls_anon_allocate_client_credentials gnutls_anon_allocate_client_credentials
+#define fn_gnutls_anon_free_client_credentials gnutls_anon_free_client_credentials
+#define fn_gnutls_bye gnutls_bye
+#define fn_gnutls_certificate_allocate_credentials gnutls_certificate_allocate_credentials
+#define fn_gnutls_certificate_free_credentials gnutls_certificate_free_credentials
+#define fn_gnutls_certificate_get_peers gnutls_certificate_get_peers
+#define fn_gnutls_certificate_set_verify_flags gnutls_certificate_set_verify_flags
+#define fn_gnutls_certificate_set_x509_crl_file gnutls_certificate_set_x509_crl_file
+#define fn_gnutls_certificate_set_x509_key_file gnutls_certificate_set_x509_key_file
+#define fn_gnutls_certificate_set_x509_trust_file gnutls_certificate_set_x509_trust_file
+#define fn_gnutls_certificate_type_get gnutls_certificate_type_get
+#define fn_gnutls_certificate_verify_peers2 gnutls_certificate_verify_peers2
+#define fn_gnutls_credentials_set gnutls_credentials_set
+#define fn_gnutls_deinit gnutls_deinit
+#define fn_gnutls_dh_set_prime_bits gnutls_dh_set_prime_bits
+#define fn_gnutls_error_is_fatal gnutls_error_is_fatal
+#define fn_gnutls_global_init gnutls_global_init
+#define fn_gnutls_global_set_log_function gnutls_global_set_log_function
+#define fn_gnutls_global_set_log_level gnutls_global_set_log_level
+#define fn_gnutls_global_set_mem_functions gnutls_global_set_mem_functions
+#define fn_gnutls_handshake gnutls_handshake
+#define fn_gnutls_init gnutls_init
+#define fn_gnutls_priority_set_direct gnutls_priority_set_direct
+#define fn_gnutls_record_check_pending gnutls_record_check_pending
+#define fn_gnutls_record_recv gnutls_record_recv
+#define fn_gnutls_record_send gnutls_record_send
+#define fn_gnutls_strerror gnutls_strerror
+#define fn_gnutls_transport_set_errno gnutls_transport_set_errno
+#define fn_gnutls_transport_set_ptr2 gnutls_transport_set_ptr2
+#define fn_gnutls_x509_crt_check_hostname gnutls_x509_crt_check_hostname
+#define fn_gnutls_x509_crt_deinit gnutls_x509_crt_deinit
+#define fn_gnutls_x509_crt_import gnutls_x509_crt_import
+#define fn_gnutls_x509_crt_init gnutls_x509_crt_init
+
+#endif /* !WINDOWSNT */
+
+\f
+/* Function to log a simple message. */