#include "error.h"
// for the error_desc tables
#include "sock.h"
#include "sock_gnutls.h"
#include <string.h>
#include <stdio.h>
struct error_desc _core_error_desc[] = {
{ ERR_CALLOC, "calloc", ERR_EXTRA_NONE },
{ ERR_STRDUP, "strdup", ERR_EXTRA_NONE },
{ ERR_GETADDRINFO, "getaddrinfo", ERR_EXTRA_GAI },
{ ERR_GETADDRINFO_EMPTY, "getaddrinfo: no results", ERR_EXTRA_NONE },
{ ERR_EVENT_NEW, "event_new", ERR_EXTRA_NONE },
{ ERR_EVENT_ADD, "event_add", ERR_EXTRA_NONE },
{ ERR_EVSQL_NEW_PQ, "evsql_new_pq", ERR_EXTRA_NONE },
{ _ERR_INVALID, NULL, 0 }
}, _sock_error_desc[] = {
{ ERR_SOCKET, "socket", ERR_EXTRA_ERRNO },
{ ERR_CONNECT, "connect", ERR_EXTRA_ERRNO },
{ ERR_READ, "read", ERR_EXTRA_ERRNO },
{ ERR_READ_EOF, "read: EOF", ERR_EXTRA_NONE },
{ ERR_WRITE, "write", ERR_EXTRA_ERRNO },
{ ERR_WRITE_EOF, "write: EOF", ERR_EXTRA_NONE },
{ ERR_FCNTL, "fcntl", ERR_EXTRA_ERRNO },
{ ERR_CLOSE, "close", ERR_EXTRA_ERRNO },
{ _ERR_INVALID, NULL, 0 }
}, _sock_gnutls_error_desc[] = {
{ ERR_GNUTLS_CERT_ALLOC_CRED, "gnutls_certificate_allocate_credentials", ERR_EXTRA_GNUTLS },
{ ERR_GNUTLS_GLOBAL_INIT, "gnutls_global_init", ERR_EXTRA_GNUTLS },
{ ERR_GNUTLS_SET_DEFAULT_PRIORITY, "gnutls_set_default_priority", ERR_EXTRA_GNUTLS },
{ ERR_GNUTLS_CRED_SET, "gnutls_credentials_set", ERR_EXTRA_GNUTLS },
{ ERR_GNUTLS_HANDSHAKE, "gnutls_handshake", ERR_EXTRA_GNUTLS },
{ ERR_GNUTLS_RECORD_SEND, "gnutls_record_send", ERR_EXTRA_GNUTLS },
{ ERR_GNUTLS_RECORD_RECV, "gnutls_record_recv", ERR_EXTRA_GNUTLS },
{ ERR_GNUTLS_RECORD_GET_DIRECTION, "gnutls_record_get_direction", ERR_EXTRA_GNUTLS },
{ _ERR_INVALID, NULL, 0 }
}, _irc_proto_error_desc[] = {
{ ERR_LINE_TOO_LONG, "IRC line is too long", ERR_EXTRA_NONE },
{ ERR_LINE_INVALID_TOKEN, "Illegal token value for IRC line", ERR_EXTRA_NONE },
{ ERR_INVALID_NM, "Invalid nickmask", ERR_EXTRA_NONE },
{ ERR_INVALID_NICK_LENGTH, "Nickname is too long", ERR_EXTRA_NONE },
{ _ERR_INVALID, NULL, 0 }
};
/**
* Array of error_desc tables
*/
static struct error_desc* _desc_tables[] = {
_core_error_desc,
_sock_error_desc,
_sock_gnutls_error_desc,
_irc_proto_error_desc,
NULL
};
/**
* Look up the error_desc for the given error code
*/
static const struct error_desc* error_lookup_desc (err_t code)
{
struct error_desc **desc_table, *desc = NULL;
// iterate over each defined error_desc array
for (desc_table = _desc_tables; desc_table; desc_table++) {
for (desc = *desc_table; desc->code && desc->name; desc++) {
// compare code
if (desc->code == code)
// found
return desc;
}
}
// not found
return NULL;
}
const char *error_name (err_t code)
{
const struct error_desc *desc;
// do we have an error_desc for it?
if ((desc = error_lookup_desc(code)))
return desc->name;
else
// unknown
return "[unknown]";
}
const char *error_msg (const struct error_info *err)
{
static char msg[ERROR_MSG_MAXLEN];
const struct error_desc *desc;
// do we have an error_desc for it?
if ((desc = error_lookup_desc(err->code)) == NULL)
// ???
snprintf(msg, ERROR_MSG_MAXLEN, "[%#.8x]: %#.8x", err->code, err->extra);
else
// intrepret .extra
switch (desc->extra_type) {
case ERR_EXTRA_NONE:
// no additional info
snprintf(msg, ERROR_MSG_MAXLEN, "%s", desc->name);
break;
case ERR_EXTRA_ERRNO:
// strerror
snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, strerror(err->extra));
break;
case ERR_EXTRA_GAI:
// gai_strerror
snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gai_strerror(err->extra));
break;
case ERR_EXTRA_GNUTLS:
// gnutls_strerror
snprintf(msg, ERROR_MSG_MAXLEN, "%s: %s", desc->name, gnutls_strerror(err->extra));
break;
default:
// ???
snprintf(msg, ERROR_MSG_MAXLEN, "%s: %#.8x", desc->name, err->extra);
break;
}
// return static pointer
return msg;
}