#include "error.h"
#include <string.h>
#include <stdio.h>
#include <netdb.h>
#include <gnutls/gnutls.h>
/*
* Helper macros
*/
#define ERROR_NAME(code, name) case code: return name
const char *error_name (err_t code)
{
switch (code) {
ERROR_NAME( ERR_CALLOC, "calloc" );
ERROR_NAME( ERR_GETADDRINFO, "getaddrinfo" );
ERROR_NAME( ERR_GETADDRINFO_EMPTY, "getaddrinfo" );
ERROR_NAME( ERR_SOCKET, "socket" );
ERROR_NAME( ERR_CONNECT, "connect" );
ERROR_NAME( ERR_READ, "read" );
ERROR_NAME( ERR_WRITE, "write" );
ERROR_NAME( ERR_GNUTLS_CERT_ALLOC_CRED, "gnutls_certificate_allocate_credentials" );
ERROR_NAME( ERR_GNUTLS_GLOBAL_INIT, "gnutls_global_init" );
ERROR_NAME( ERR_GNUTLS_INIT, "gnutls_init" );
ERROR_NAME( ERR_GNUTLS_SET_DEFAULT_PRIORITY, "gnutls_set_default_priority" );
ERROR_NAME( ERR_GNUTLS_CRED_SET, "gnutls_credentials_set" );
ERROR_NAME( ERR_GNUTLS_HANDSHAKE, "gnutls_handshake" );
default: return "[unknown]";
}
}
const char *error_msg (struct error_info *err)
{
static char msg[ERROR_MSG_MAXLEN];
// intrepret .extra
switch (err->code & _ERR_EXTRA_MASK) {
case ERR_EXTRA_NONE:
// no additional info
snprintf(msg, ERROR_MSG_MAXLEN, "%s", error_name(err->code));
break;
case ERR_EXTRA_ERRNO:
// strerror
snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", error_name(err->code), strerror(err->extra));
break;
case ERR_EXTRA_GAI:
// gai_strerror
snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", error_name(err->code), gai_strerror(err->extra));
break;
case ERR_EXTRA_GNUTLS:
// gnutls_strerror
snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", error_name(err->code), gnutls_strerror(err->extra));
break;
default:
// ???
snprintf(msg, ERROR_MSG_MAXLEN, "%s(%#.8x): %#.8x", error_name(err->code), err->code, err->extra);
break;
}
// return static pointer
return msg;
}